pyinstaller 出现OSError:Cannot load native module ‘Crypto.Cipher._raw_ecb‘的一种解决方法

pyinstaller 出现OSError:Cannot load native module 'Crypto.Cipher._raw_ecb’的一种解决方法

找到[https://www.twblogs.net/a/5b7f594a2b717767c6af1a3f/zh-cn] 测试可以,原始的解决在[https://raw.githubusercontent.com/pyinstaller/pyinstaller/develop/PyInstaller/hooks/hook-Crypto.py]


博主优化后的是:

```python
import os
import glob

from PyInstaller.compat import EXTENSION_SUFFIXES
from PyInstaller.utils.hooks import get_module_file_attribute

binaries = []
binary_module_names = [
    'Crypto.Math',      # First in the list
    'Crypto.Cipher',
    'Crypto.Util',
    'Crypto.Hash',
    'Crypto.Protocol',
]

try:
    for module_name in binary_module_names:
        m_dir = os.path.dirname(get_module_file_attribute(module_name))
        for ext in EXTENSION_SUFFIXES:
            module_bin = glob.glob(os.path.join(m_dir, '_*%s' % ext))
            for f in module_bin:
                binaries.append((f, module_name.replace('.', os.sep)))
except ImportError:
    # Do nothing for PyCrypto (Crypto.Math does not exist there)
    pass

保存到 C:\python27\Lib\site-packages\PyInstaller\hooks,文件名是hook-Crypto.py,之后关键的是要重启CMD控制端,如果之前有打包过的,把pyinstaller的build里面的该打包程序的文件夹删除,还有spec的一起删除,重新打包就可以

作者:pixyon
链接:https://www.jianshu.com/p/7a693b687d6c

OSError:Cannot load native module ‘Crypto.Cipher._raw_ecb’:Trying ‘_raw_ecb.cp36-win_amd64.pyd’:cannot load library 'C:\Users\admin\AppData\Local\Temp_MEI160382\Crypto\Util…\Cipher_raw_ecb.cp36-win_amb64.pyd’是在使用pyinstaller常出现的问题,现已解决,我出现这个问题是因为python通过pip3 install pyinstaller没有重定位Crypto的钩子

解决方法:

1.在github给出的解决方案中拷贝相关代码,在本地新建一个叫 hook-Crypto.py 的文件,并把拷贝的代码保存进改文件中

   github解决方案网址:https://raw.githubusercontent.com/pyinstaller/pyinstaller/develop/PyInstaller/hooks/hook-Crypto.py

   里面的相关代码:hook-Crypto.py

import os
import glob
 
from PyInstaller.compat import EXTENSION_SUFFIXES
from PyInstaller.utils.hooks import get_module_file_attribute
 
binaries = []
binary_module_names = [
    'Crypto.Math',      # First in the list
    'Crypto.Cipher',
    'Crypto.Util',
    'Crypto.Hash',
    'Crypto.Protocol',
]
 
try:
    for module_name in binary_module_names:
        m_dir = os.path.dirname(get_module_file_attribute(module_name))
        for ext in EXTENSION_SUFFIXES:
            module_bin = glob.glob(os.path.join(m_dir, '_*%s' % ext))
            for f in module_bin:
                binaries.append((f, module_name.replace('.', os.sep)))
except ImportError:
    # Do nothing for PyCrypto (Crypto.Math does not exist there)
    pass

2.然后把该钩子放入你的python的库文件中,通常为:~\python3.63\Lib\site-packages\PyInstaller\hooks中

3.重启该cmd即可

所有方法都来自互联网,我做了个全套总结

pycrypto,pycrytodome和crypto是一个东西,在很久以前,crypto在python上面的名字是pycrypto它是一个第三方库,但是已经停止更新三年了,所以不建议安装这个库;但有一个延伸版pycryptodome,用法和pycrypto一模一样的,正常用pip安装就OK:
pip install pycryptodome

安装完之后,去C:\Python36\Lib\site-packages文件夹(python安装目录的第三方库)下找到crypto文件夹,改成Crypto,‘C’改成大写,然后用测试代码验证:我用的CFB模式,不限制明文的长度,比较简单

#AES-dome
# -*- coding: utf-8 -*-
import base64
import os
from Crypto.Cipher import AES
'''
采用AES CFB模式 对称加密算法
CFB模式,对待加密原文长度没有要求
'''
class AES_encrypt_decrypt(object):
    def __init__(self, key):
        self.key = key.encode('utf-8')
        self.mode = AES.MODE_CFB
 
    # 加密函数,采用CFB方式,text明文没有长度限制
    def encrypt(self, text):
        text = text.encode('utf-8')
        #注意,这里Python3.6下用AES传递key时必须要转换成2进制,key前面要加'b'
        crypto = AES.new(self.key, self.mode, b'woshigongyao6666')
        # 这里密钥key 长度必须为16(AES-128),
        # 24(AES-192),或者32 (AES-256)Bytes 长度
        # 目前AES-128 足够目前使用
        self.ciphertext = crypto.encrypt(text)
        # 因为AES加密时候得到的字符串不一定是ascii字符集的,输出到终端或者保存时候可能存在问题
        # 所以这里统一用base64转化为字符串
        return str(base64.encodebytes(self.ciphertext), encoding='utf-8')
 
    # 解密
    def decrypt(self, text):
        crypto = AES.new(self.key, self.mode, b'woshigongyao6666')
        plain_text = crypto.decrypt(base64.decodebytes(text.encode(encoding='utf-8')))
        return bytes.decode(plain_text)
 
if __name__ == '__main__':
    # 初始化密钥
    sql = AES_encrypt_decrypt('woshisiyao666888')
    text = 'my AES encrypt program!'
    e = pc.encrypt(text)  # 加密
    d = pc.decrypt(e)  # 解密
    print("原文:"+'\n'+text)
    print("加密结果:"+'\n'+ e)
    print("解密结果:"+'\n'+d)

运行上面的程序,应该可以跑出来这样的结果:

原文:
my AES encrypt program!
加密结果:
DyMSIDSVV6zp8r2XtcPEHaWlqcNuEOA=
 
解密结果:
my AES encrypt program!

好,下面开始用Pyinstaller打包,但无奈报错,经过网上一顿找,发现原因大致如下,延续开发的人漏了hook,需要手动加一个hook文件到C:\python36\Lib\site-packages\PyInstaller\hooks,文件名是hook-Crypto.py,内容如下:

#-----------------------------------------------------------------------------
# Copyright (c) 2005-2018, PyInstaller Development Team.
#
# Distributed under the terms of the GNU General Public License with exception
# for distributing bootloader.
#
# The full license is in the file COPYING.txt, distributed with this software.
#-----------------------------------------------------------------------------
 
"""
Hook for PyCryptodome library: https://pypi.python.org/pypi/pycryptodome
PyCryptodome is an almost drop-in replacement for the now unmaintained
PyCrypto library. The two are mutually exclusive as they live under
the same package ("Crypto").
PyCryptodome distributes dynamic libraries and builds them as if they were
Python C extensions (even though they are not extensions - as they can't be
imported by Python). It might sound a bit weird, but this decision is rooted
in PyPy and its partial and slow support for C extensions. However, this also
invalidates several of the existing methods used by PyInstaller to decide the
right files to pull in.
Even though this hook is meant to help with PyCryptodome only, it will be
triggered also when PyCrypto is installed, so it must be tested with both.
Tested with PyCryptodome 3.5.1, PyCrypto 2.6.1, Python 2.7 & 3.6, Fedora & Windows
"""
 
import os
import glob
 
from PyInstaller.compat import EXTENSION_SUFFIXES
from PyInstaller.utils.hooks import get_module_file_attribute
 
# Include the modules as binaries in a subfolder named like the package.
# Cryptodome's loader expects to find them inside the package directory for
# the main module. We cannot use hiddenimports because that would add the
# modules outside the package.
 
binaries = []
binary_module_names = [
    'Crypto.Math',      # First in the list
    'Crypto.Cipher',
    'Crypto.Util',
    'Crypto.Hash',
    'Crypto.Protocol',
]
 
try:
    for module_name in binary_module_names:
        m_dir = os.path.dirname(get_module_file_attribute(module_name))
        for ext in EXTENSION_SUFFIXES:
            module_bin = glob.glob(os.path.join(m_dir, '_*%s' % ext))
            for f in module_bin:
                binaries.append((f, module_name.replace('.', os.sep)))
except ImportError:
    # Do nothing for PyCrypto (Crypto.Math does not exist there)
    pass

保存之后,拷贝到那个目录,重新用Pyinstaller打包,完美生成EXE文件!

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
您可以在GitHub上找到Crypto.Cipher的相关代码库。参考中提供了一种在GitHub上找到Crypto.Cipher代码的方法。您可以访问以下链接获取该代码库:https://raw.githubusercontent.com/pyinstaller/pyinstaller/develop/PyInstaller/hooks/hook-Crypto.py。这个代码库中包含了与Crypto.Cipher相关的代码。您可以在本地新建一个名为hook-Crypto.py的文件,并将从该代码库中拷贝的代码保存在其中。这样,您就可以使用这些代码来进行您的项目开发了。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [pyinstaller 在支持python3.6+出现OSError:Cannot load native module 'Crypto.Cipher._raw_ecb'的一种解决...](https://blog.csdn.net/play_841266670/article/details/81629314)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [pyinstaller 出现OSError:Cannot load native moduleCrypto.Cipher._raw_ecb‘的一种解决方法](https://blog.csdn.net/weixin_45813782/article/details/123359930)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值