在 64 位 Windows 上获取和安装 crypto.dll

where to get and install crypto.dll on 64 bit Windows

注意:这不是 Visual Studio 的问题,而是不兼容的 dll 版本的问题。下面的步骤复制了这个问题,因为 运行ning in Visual Studio 在调试模式下会因抛出异常而中断。如果你只是运行,抛出的异常在别处处理,程序运行正常。但由于我在调试模式下花费了很多时间,所以我更愿意解决这个问题。

调试时,我希望能够进入我在 Visual Studio 中添加到我的虚拟环境中的模块。我收到无法修复的 'library not found' 错误。以下是步骤:

  1. 在 Visual Studio 中创建一个新的 Python 应用程序。
  2. 为该应用程序创建一个虚拟环境(Python 3.6 64 位)。
  3. pip install twilio 进入您的虚拟环境。你得到 以下输出。

...

   ----- Installing 'twilio' -----
Collecting twilio
  Using cached twilio-6.10.5-py2.py3-none-any.whl
Collecting pytz (from twilio)
  Using cached pytz-2018.3-py2.py3-none-any.whl
Collecting six (from twilio)
  Using cached six-1.11.0-py2.py3-none-any.whl
Collecting PyJWT>=1.4.2 (from twilio)
  Using cached PyJWT-1.6.0-py2.py3-none-any.whl
Collecting requests>=2.0.0; python_version >= "3.0" (from twilio)
  Using cached requests-2.18.4-py2.py3-none-any.whl
Collecting pysocks; python_version >= "3.0" (from twilio)
  Using cached PySocks-1.6.8.tar.gz
Collecting certifi>=2017.4.17 (from requests>=2.0.0; python_version >= "3.0"->twilio)
  Using cached certifi-2018.1.18-py2.py3-none-any.whl
Collecting chardet<3.1.0,>=3.0.2 (from requests>=2.0.0; python_version >= "3.0"->twilio)
  Using cached chardet-3.0.4-py2.py3-none-any.whl
Collecting urllib3<1.23,>=1.21.1 (from requests>=2.0.0; python_version >= "3.0"->twilio)
  Using cached urllib3-1.22-py2.py3-none-any.whl
Collecting idna<2.7,>=2.5 (from requests>=2.0.0; python_version >= "3.0"->twilio)
  Using cached idna-2.6-py2.py3-none-any.whl
Installing collected packages: pytz, six, PyJWT, certifi, chardet, urllib3, idna, requests, pysocks, twilio
  Running setup.py install for pysocks: started
    Running setup.py install for pysocks: finished with status 'done'
Successfully installed PyJWT-1.6.0 certifi-2018.1.18 chardet-3.0.4 idna-2.6 pysocks-1.6.8 pytz-2018.3 requests-2.18.4 six-1.11.0 twilio-6.10.5 urllib3-1.22
----- Successfully installed 'twilio' -----
  1. 将以下行添加到 .py 文件的顶部:

    from twilio.rest import Client

  2. 在 Visual Studio 中转到工具 > 选项 > python > 调试。制作 确定 'Enable debugging of Python standard library' 已选中

  3. 运行 申请。您收到以下错误:

ModuleNotFoundError: No module named 'OpenSSL'

  1. pip install pyopenssl 你得到以下输出:

...

----- Installing 'pyopenssl' -----
Collecting pyopenssl
  Using cached pyOpenSSL-17.5.0-py2.py3-none-any.whl
Requirement already satisfied: six>=1.5.2 in c:\users\x\source\repos\pythonapplication9\pythonapplication9\env\lib\site-packages (from pyopenssl)
Collecting cryptography>=2.1.4 (from pyopenssl)
  Using cached cryptography-2.1.4-cp36-cp36m-win_amd64.whl
Requirement already satisfied: idna>=2.1 in c:\users\x\source\repos\pythonapplication9\pythonapplication9\env\lib\site-packages (from cryptography>=2.1.4->pyopenssl)
Collecting cffi>=1.7; platform_python_implementation != "PyPy" (from cryptography>=2.1.4->pyopenssl)
  Using cached cffi-1.11.5-cp36-cp36m-win_amd64.whl
Collecting asn1crypto>=0.21.0 (from cryptography>=2.1.4->pyopenssl)
  Using cached asn1crypto-0.24.0-py2.py3-none-any.whl
Collecting pycparser (from cffi>=1.7; platform_python_implementation != "PyPy"->cryptography>=2.1.4->pyopenssl)
  Using cached pycparser-2.18.tar.gz
Installing collected packages: pycparser, cffi, asn1crypto, cryptography, pyopenssl
  Running setup.py install for pycparser: started
    Running setup.py install for pycparser: finished with status 'done'
Successfully installed asn1crypto-0.24.0 cffi-1.11.5 cryptography-2.1.4 pycparser-2.18 pyopenssl-17.5.0
----- Successfully installed 'pyopenssl' -----
  1. 运行 申请。您收到以下错误:

    asn1crypto._ffi.LibraryNotFoundError: The library libcrypto could not be found

asn1crypto 中名为 _big_num_ctypes.py 的文件中引发错误。抛出这个的代码行是:

libcrypto_path = find_library(b'crypto' if sys.version_info < (3,) else 'crypto')
if not libcrypto_path:
    raise LibraryNotFoundError('The library libcrypto could not be found')

更新: 我被要求提供完整的回溯。我这样修改代码打印出来:

import unittest
import traceback

class Test_test1(unittest.TestCase):
    def test_A(self):
        try:
            from twilio.rest import Client
        except Exception as e:
            print('foo')
            foo = traceback.extract_stack()
            traceback.print_exc(e)

if __name__ == '__main__':
    unittest.main()

和之前一样,import 行抛出异常,但未捕获到异常,'except' 子句中的行永远不会执行 来自 twilio.rest 导入客户端

更新 2:我以某种方式在@Prateek 和@user8212173 之后让它工作。但现在它不再工作了。正如两者所建议的那样,问题是 crypto.dll 不存在。所以我通过以下步骤添加它但没有成功:

  1. 我从 https://slproweb.com/products/Win32OpenSSL.html (pointed to from https://wiki.openssl.org/index.php/Binaries) 安装了 Win64 OpenSSL v1.1.0j。它不包含 crypto.dll。
  2. 然后我从 http://www.dlldownloader.com/crypto-dll/ (as @user8212173 suggested) (there is only a 32 bit version) and followed the instructions. I then got a new error message "ImportError: DLL load failed: %1 is not a valid Win32 application" which means that the crypto.dll I installed has a version conflict (I am running 64bit python on a 64bit computer). I remember installing it from Unofficial Windows Binaries for Python Extension Packages 安装了 crypto.dll 我在那里找不到它。那么,我在哪里可以获得 crypto.dll 的 64 位工作版本?

我搜索了很多,发现您缺少 crypto.dll 文件。您的代码正在寻找此 dll 文件,但无法找到它。

请注意,pip install crypto 不会安装它,因为这是 python 库,代码正在寻找 dll 文件。

ctypes.util.find_library 从 windows 环境路径变量中搜索 dll 文件。

Reference : find_library() in ctypes

为了验证我检查了。

find_library('l2gpstore')
>>'C:\WINDOWS\system32\l2gpstore.dll'
find_library('java')
>>'C:\Program Files\Java\jdk-9.0.4\bin\java.dll'

此外,您应该从这里

安装 OpenSSLlibcrypto 模块

OpenSSL

OpenSSL 安装instructions

The master sources are maintained in our git repository, which is accessible over the network and cloned on GitHub, at https://github.com/openssl/openssl. Bugs and pull patches (issues and pull requests) should be file on the GitHub repo. Please familiarize yourself with the license.

关于 OpenSSL 的 libcrypto

reference : GitHub

libcrypto (with platform specific naming): Provides general cryptographic and X.509 support needed by SSL/TLS but not logically part of it.

安装二进制文件并检查 crypto.dll 在环境变量的其中一个路径字符串中可用后,此问题应该得到解决。

如果没有添加到路径变量中检查。

更新:

更新,因为问题已经更新,问题又出现了。

与 1.0.2 相比,OpenSSL 1.1.0 的架构发生了变化

September 13, 2018 - OpenSSL 1.1.0 and later are quite different from previous releases. Users should install BOTH the 1.0.2 series (LTS) and the 1.1.1 (LTS) series for maximum application compatibility. Developers need to recompile their software to support 1.1.1. See the official OpenSSL release strategy document for more details. – Prateek yesterday

如果您从 Github 打开 1.0.2,您可以看到 crypto.h 文件,最新版本中缺少相同的文件。 OpenSSL DLL 名字也有变化,他们 renamed libeay32 to libcrypto

您需要 post 使用 post 中的 asn1crypto 库的代码。在您的 post 中没有明确使用 asn1crypto 的代码。因此,无法使用 pipenv 重现您的问题。

确保您也使用更新的库。

不建议从不可靠的来源下载 DLL 源,例如 DLLdownloader


如果您在使用最新版本的 OpenSSLasn1crypto 时遇到问题,最好将 OpenSSL 降级为 1.0.2 ,考虑到它附带crypto.h 文件。

祝你好运!

我试图在我的计算机上重现错误,当我 运行 "error-producing" 文件 _big_num_ctypes.py 时成功了。虽然,我没有 Visual Studio,但错误源于缺少 crypto.dll 文件。我们将推导出这个step-by-step。让我们首先检查文件 _big_num_ctypes.py:

中导致错误的代码片段
#imports
from ctypes.util import find_library
.
.
from .._ffi import LibraryNotFoundError, FFIEngineError

try:
# On Python 2, the unicode string here may raise a UnicodeDecodeError as it
# tries to join a bytestring path to the unicode name "crypto"
    libcrypto_path = find_library(b'crypto' if sys.version_info < (3,) else 'crypto')
    if not libcrypto_path:
        raise LibraryNotFoundError('The library libcrypto could not be found')
.
.
except (AttributeError):
    raise FFIEngineError('Error initializing ctypes')

我运行文件:

C:\>cd "C:\ProgramData\Anaconda3\Lib\site-packages\asn1crypto\_perf"
C:\ProgramData\Anaconda3\Lib\site-packages\asn1crypto\_perf>python _big_num_ctypes.py

并且有一个 Traceback 用于库导入:

Traceback (most recent call last):
  File "_big_num_ctypes.py", line 27, in <module>
    from .._ffi import LibraryNotFoundError, FFIEngineError
ValueError: attempted relative import beyond top-level package

因此,我将.ffi的导入路径更改为:

from asn1crypto._ffi import LibraryNotFoundError, FFIEngineError

第二次运行出现了缺少libcrypto库的错误:

asn1crypto._ffi.LibraryNotFoundError: The library libcrypto could not be found

当无法在 C:\Windows\System32 [=77] 找到名为 cryptodll 库时引发异常=] SYSWOW64(对于 64 位)

libcrypto_path = find_library(b'crypto' if sys.version_info < (3,) else 'crypto')

find_library 的目的是找到一个指定的库和 return 一个路径名。如 docs 中所述,此方法的行为因 OS 而异。如果此方法找不到任何包,它 returns None.

>>> from ctypes.util import find_library
>>> print(find_library("c"))
None

在我们的例子中,搜索的是 crypto.dll,但我在我的计算机上找不到该文件。所以,我完全按照说明下载安装了here。当我再次检查时:

 >>> find_library('crypto')
'C:\windows\system32\crypto.dll'

现在我 运行 python _big_num_ctypes.py 又得到了一个不同的 Traceback:

    Traceback (most recent call last):
  File "_big_num_ctypes.py", line 37, in <module>
    libcrypto = CDLL(libcrypto_path)
  File "C:\ProgramData\Anaconda3\lib\ctypes\__init__.py", line 348, in __init__
    self._handle = _dlopen(self._name, mode)
OSError: [WinError 193] %1 is not a valid Win32 application

对上述错误的进一步调查表明,如果我将 32 位 DLL 与 64 位 Python 或 vice-versa 一起使用,那么我可能会遇到 here 中解释的此类错误.因此,我安装了 Python 3.6 32 位并再次尝试使用 py -3.6-32 _big_num_ctypes.py。我也安装了所有必需的包,但这个错误仍然存​​在。

我们可能需要 Crypto 包的 32 位二进制文​​件吗?这 answer and this 提供了更多信息。

我意识到 Pycryptodome 是一个定期维护的包,比旧的 Crypto 包更受欢迎,但仍然可以安装在 Crypto 下。另一点需要注意的是,此软件包的要求之一是 MS Visual Studio 2015(社区版)和 C/C++ 编译器以及仅可再分发的。目前可能缺少某些 C++ 编译器文件或 MS Visual Studio 文件并导致这些问题发生。

如果您安装了上述所有先决条件,crypto.dll 文件和 Pycryptodome 程序包,我相信这个错误将会得到解决。您已经安装了其他必需的软件包 OpenSSL & Twilio。不幸的是,我被限制在我的计算机上安装 MS Visual Studio,所以我无法进一步测试它。

我也 运行 unittest 代码,它 运行 对我来说成功了:

#Output

.
----------------------------------------------------------------------
Ran 1 test in 0.771s

OK

这是我针对 windows 10、visual studio 社区 2017、

的解决方案

打开文件 C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python36_64\Lib\site-packages\asn1crypto_perf_big_num_ctypes.py 然后将代码从 :

libcrypto_path = find_library(b'crypto' if sys.version_info < (3,) else 'crypto')

至:

libcrypto_path = find_library(b'crypto' if sys.version_info < (3,) else 'libcrypto')

然后错误消息消失了。

libcrypto.dll 已经在文件夹 C:\Windows\System32\