Python负载存储的证书私钥
在Windows服务器上,我正在尝试获取存储证书的私钥。
在服务器上,我有:
- 存储在本地计算机中的证书,该证书是可导出的从PXF文件安装的。
- Python 3.7.0
- 密码pip Packake版本37.0.2
- Windows Server 2019
问题:
我的脚本无法从已加载的PEM中估算关键数据。
注意:我可以成功地使用原始证书PFX文件来创建用于(对Azure)
Code00.py的目的:
import ssl
from cryptography import x509
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes,serialization
expected_thumbprint = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
def hex_string_readable(bytes):
return ["{:02X}".format(x) for x in bytes]
for c in ssl.enum_certificates("MY"):
data = c[0]
pem_data = ssl.DER_cert_to_PEM_cert(data).encode()
cert_details = x509.load_pem_x509_certificate(pem_data, default_backend())
fingerprint = hex_string_readable(cert_details.fingerprint(hashes.SHA1()))
fingerprint_string = ''.join(fingerprint)
print(fingerprint_string)
if fingerprint_string == expected_thumbprint:
print("Certificate found!")
private_key = serialization.load_pem_private_key(pem_data, None, backend=default_backend())
break
结果:
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Certificate found!
Traceback (most recent call last):
File ".\code00.py", line 22, in <module>
private_key = serialization.load_pem_private_key(pem_data, None, backend=default_backend())
File "C:\temp\.venv\lib\site-packages\cryptography\hazmat\primitives\serialization\base.py", line 22, in load_pem_private_key
return ossl.load_pem_private_key(data, password)
File "C:\temp\.venv\lib\site-packages\cryptography\hazmat\backends\openssl\backend.py", line 904, in load_pem_private_key
password,
File "C:\temp\.venv\lib\site-packages\cryptography\hazmat\backends\openssl\backend.py", line 1168, in _load_key
self._handle_key_loading_error()
File "C:\temp\.venv\lib\site-packages\cryptography\hazmat\backends\openssl\backend.py", line 1193, in _handle_key_loading_error
"Could not deserialize key data. The data may be in an "
ValueError: Could not deserialize key data. The data may be in an incorrect format or it may be encrypted with an unsupported algorithm.
我有没有做错事或其他方法来实现此目标?
提前致谢。
On a Windows server I'm trying to get the private key of a stored certificate.
On the server, I have:
- The certificate stored in Local Machine My, installed from a PXF file as exportable.
- Python 3.7.0
- cryptography pip package version 37.0.2
- Windows Server 2019
Problem:
My script fails to deserialize key data from the loaded PEM.
Note: I could successfully use the original certificate PFX file for the purpose it has been created for (authenticate to Azure)
code00.py:
import ssl
from cryptography import x509
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes,serialization
expected_thumbprint = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
def hex_string_readable(bytes):
return ["{:02X}".format(x) for x in bytes]
for c in ssl.enum_certificates("MY"):
data = c[0]
pem_data = ssl.DER_cert_to_PEM_cert(data).encode()
cert_details = x509.load_pem_x509_certificate(pem_data, default_backend())
fingerprint = hex_string_readable(cert_details.fingerprint(hashes.SHA1()))
fingerprint_string = ''.join(fingerprint)
print(fingerprint_string)
if fingerprint_string == expected_thumbprint:
print("Certificate found!")
private_key = serialization.load_pem_private_key(pem_data, None, backend=default_backend())
break
Result:
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Certificate found!
Traceback (most recent call last):
File ".\code00.py", line 22, in <module>
private_key = serialization.load_pem_private_key(pem_data, None, backend=default_backend())
File "C:\temp\.venv\lib\site-packages\cryptography\hazmat\primitives\serialization\base.py", line 22, in load_pem_private_key
return ossl.load_pem_private_key(data, password)
File "C:\temp\.venv\lib\site-packages\cryptography\hazmat\backends\openssl\backend.py", line 904, in load_pem_private_key
password,
File "C:\temp\.venv\lib\site-packages\cryptography\hazmat\backends\openssl\backend.py", line 1168, in _load_key
self._handle_key_loading_error()
File "C:\temp\.venv\lib\site-packages\cryptography\hazmat\backends\openssl\backend.py", line 1193, in _handle_key_loading_error
"Could not deserialize key data. The data may be in an "
ValueError: Could not deserialize key data. The data may be in an incorrect format or it may be encrypted with an unsupported algorithm.
Is there anything I'm doing wrong or other ways to achieve this goal?
Thanks in advance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我可能迟到了聚会,但这可能会对以后的某人有所帮助。
在您的代码中,您实际上是在Windows证书存储中搜索已加载的证书。 SSL库加载了这些库,但是从我看来,它仅加载证书的公共部分。如果您拥有仅对服务器进行身份验证的TLS客户端,则足够了,但是如果您具有双向身份验证或TLS服务器,并且需要使用Windows证书存储的东西变得困难。
困难在于,Windows Crypto API仅允许通过一个将PFX格式导出到文件或内存中的功能允许专用密钥导出。如您提到的,您已经有PFX文件,其中包括私钥。您可以使用它并将其加载到Python代码中:
此功能的结果为您提供所需的一切,以便其他方面对您进行身份验证。私钥显然包含在私有键变量中,并且通过组合证书和额外的观点获得了证书链。
如果您需要将其加载到SSL上下文中,一个解决方案将是使用指定的管道,因为SSL上下文仅允许以PEM格式加载证书链和私钥。这对Linux非常有用,但是在Windows和其证书商店配对的情况下很痛苦。
I'm probably late to the party, but this might help to someone in the future.
In your code you are actually searching through loaded certificates from Windows Certificate Store. Ssl library loads those, but from what I could see, it loads only public part of the certificates. This is enough if you have TLS client which only authenticates server, but if you have two-way authentication or TLS server and you need to use Windows Certificate Store things get difficult.
The difficulty lies in the fact that Windows crypto API allows private key export only through one function which exports PFX format either into file or into memory. As you mentioned, you already have PFX file which includes private key. You can use that and load it into Python code with something like this:
Result of this function gets you everything you need in order for other side to authenticate you. Private key is contained in privateKey variable obviously, and certificate chain you get by combining cert and additionalCerts.
If you need to load this into SSL context, one solution would be to use named pipes, as SSL context only allows loading of certificate chain and private key from files in PEM format. This is great for Linux, but quite a pain under Windows paired with its Certificate Store.