读取 pem 证书期间出现 python 3.6 的 x509 错误
x509 error with python 3.6 during read pem certificate
在我的 python 代码中,我遇到了以下问题:
Traceback (most recent call last):
File "/tmp/mod_wsgi-localhost:5000:0/handler.wsgi", line 94, in <module>
recorder_directory=recorder_directory)
File "/usr/lib64/python3.6/site-packages/mod_wsgi/server/__init__.py", line 1400, in __init__
exec(code, self.module.__dict__)
File "/app/scripts/core.wsgi", line 1, in <module>
from core_nbi import core_ws as application
File "/app/core_if_nbi.py", line 357, in <module>
coreApi.start()
File "/app/core.py", line 250, in wrapper
return func(self, *args, **kwargs)
File "/app/core.py", line 646, in start
self.otkHandler.loadCertificate()
File "/app/core.py", line 294, in loadCertificate
default_backend())
File "/usr/lib64/python3.6/site-packages/cryptography/x509/base.py", line 50, in load_pem_x509_certificate
return backend.load_pem_x509_certificate(data)
File "/usr/lib64/python3.6/site-packages/cryptography/hazmat/backends/openssl/backend.py", line 1143, in load_pem_x509_certificate
mem_bio = self._bytes_to_bio(data)
File "/usr/lib64/python3.6/site-packages/cryptography/hazmat/backends/openssl/backend.py", line 454, in _bytes_to_bio
data_ptr = self._ffi.from_buffer(data)
TypeError: from_buffer() cannot return the address of a unicode object
失败的代码如下:
certificate = x509.load_pem_x509_certificate(
certificate_file.read(),
default_backend())
# backend=default_backend())
self.public_key = certificate.public_key()
请注意,在 python 2.7 版本中,此代码有效。
现在我必须更改我的 python 版本并且我还更新了模块。
我尝试读取的证书是有效的 PEM 证书,以 :
开头
-----BEGIN CERTIFICATE-----
MIIFgjCCA2oCCQD7TLSQ/uU4AjANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMC
4y34NPO08tUuRauZvhejBWLlv1yC6UID0rLdkzjFd2x0hn326r3xaPMsD7BMZVXy
................................................................
O6dZxMeQwKIuDy1lQPTyleDIdKTSTX55/Dug7ey3/Ayl7Bw63H9rlEtKy8VONJrl
9G1sJf9MoktA9uPfMk0EU9B0CZzUUQ==
-----END CERTIFICATE-----
Package Version
-------------- ---------
aniso8601 7.0.0
appdirs 1.4.3
asn1crypto 0.24.0
avro-python3 1.9.0
bcrypt 3.1.7
certifi 2019.6.16
cffi 1.12.3
chardet 3.0.4
Click 7.0
cryptography 2.7
Flask 0.12.1
Flask-HTTPAuth 3.2.2
Flask-RESTful 0.3.5
idna 2.6
itsdangerous 1.1.0
Jinja2 2.10.1
kafka-python 1.4.3
MarkupSafe 1.1.1
mod-wsgi 4.5.18
netmiko 2.4.0
packaging 16.8
paramiko 2.6.0
pip 19.1.1
pycparser 2.19
PyJWT 1.5.2
pymongo 3.6.0
PyNaCl 1.3.0
pyparsing 2.2.0
pyserial 3.4
pytz 2019.1
PyYAML 5.1.1
requests 2.18.4
scp 0.13.2
setuptools 38.4.1
six 1.11.0
textfsm 0.4.1
urllib3 1.22
Werkzeug 0.15.5
pip 19.1.1 from /usr/lib/python3.6/site-packages/pip (python 3.6)
你知道如何解决这个问题吗?
load_pem_x509_certificate
采用 bytes
,而不是字符串。在 Python 2.7 中,这种区别无关紧要,但在 3.x 中,您必须先将其编码为字节。由于您是从文件中读取的,因此最好的解决方案是更改 open
调用以使用 rb
(读取二进制)作为模式,然后 certificate_file.read()
将 return字节。
在我的 python 代码中,我遇到了以下问题:
Traceback (most recent call last):
File "/tmp/mod_wsgi-localhost:5000:0/handler.wsgi", line 94, in <module>
recorder_directory=recorder_directory)
File "/usr/lib64/python3.6/site-packages/mod_wsgi/server/__init__.py", line 1400, in __init__
exec(code, self.module.__dict__)
File "/app/scripts/core.wsgi", line 1, in <module>
from core_nbi import core_ws as application
File "/app/core_if_nbi.py", line 357, in <module>
coreApi.start()
File "/app/core.py", line 250, in wrapper
return func(self, *args, **kwargs)
File "/app/core.py", line 646, in start
self.otkHandler.loadCertificate()
File "/app/core.py", line 294, in loadCertificate
default_backend())
File "/usr/lib64/python3.6/site-packages/cryptography/x509/base.py", line 50, in load_pem_x509_certificate
return backend.load_pem_x509_certificate(data)
File "/usr/lib64/python3.6/site-packages/cryptography/hazmat/backends/openssl/backend.py", line 1143, in load_pem_x509_certificate
mem_bio = self._bytes_to_bio(data)
File "/usr/lib64/python3.6/site-packages/cryptography/hazmat/backends/openssl/backend.py", line 454, in _bytes_to_bio
data_ptr = self._ffi.from_buffer(data)
TypeError: from_buffer() cannot return the address of a unicode object
失败的代码如下:
certificate = x509.load_pem_x509_certificate(
certificate_file.read(),
default_backend())
# backend=default_backend())
self.public_key = certificate.public_key()
请注意,在 python 2.7 版本中,此代码有效。 现在我必须更改我的 python 版本并且我还更新了模块。 我尝试读取的证书是有效的 PEM 证书,以 :
开头-----BEGIN CERTIFICATE-----
MIIFgjCCA2oCCQD7TLSQ/uU4AjANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMC
4y34NPO08tUuRauZvhejBWLlv1yC6UID0rLdkzjFd2x0hn326r3xaPMsD7BMZVXy
................................................................
O6dZxMeQwKIuDy1lQPTyleDIdKTSTX55/Dug7ey3/Ayl7Bw63H9rlEtKy8VONJrl
9G1sJf9MoktA9uPfMk0EU9B0CZzUUQ==
-----END CERTIFICATE-----
Package Version
-------------- ---------
aniso8601 7.0.0
appdirs 1.4.3
asn1crypto 0.24.0
avro-python3 1.9.0
bcrypt 3.1.7
certifi 2019.6.16
cffi 1.12.3
chardet 3.0.4
Click 7.0
cryptography 2.7
Flask 0.12.1
Flask-HTTPAuth 3.2.2
Flask-RESTful 0.3.5
idna 2.6
itsdangerous 1.1.0
Jinja2 2.10.1
kafka-python 1.4.3
MarkupSafe 1.1.1
mod-wsgi 4.5.18
netmiko 2.4.0
packaging 16.8
paramiko 2.6.0
pip 19.1.1
pycparser 2.19
PyJWT 1.5.2
pymongo 3.6.0
PyNaCl 1.3.0
pyparsing 2.2.0
pyserial 3.4
pytz 2019.1
PyYAML 5.1.1
requests 2.18.4
scp 0.13.2
setuptools 38.4.1
six 1.11.0
textfsm 0.4.1
urllib3 1.22
Werkzeug 0.15.5
pip 19.1.1 from /usr/lib/python3.6/site-packages/pip (python 3.6)
你知道如何解决这个问题吗?
load_pem_x509_certificate
采用 bytes
,而不是字符串。在 Python 2.7 中,这种区别无关紧要,但在 3.x 中,您必须先将其编码为字节。由于您是从文件中读取的,因此最好的解决方案是更改 open
调用以使用 rb
(读取二进制)作为模式,然后 certificate_file.read()
将 return字节。