读取 pem 证书期间 python 3.6 出现 x509 错误

Pri*_*sco 4 cryptography certificate pem x509 python-3.x

在我的 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
Run Code Online (Sandbox Code Playgroud)

失败的代码如下:

            certificate = x509.load_pem_x509_certificate(
                certificate_file.read(),
                default_backend())
#               backend=default_backend())
            self.public_key = certificate.public_key()

Run Code Online (Sandbox Code Playgroud)

值得注意的是,在 python 2.7 版本中,这段代码可以工作。现在我必须更改我的 python 版本,并且还更新了模块。我尝试读取的证书是有效的 PEM 证书,开头为:

-----BEGIN CERTIFICATE-----
MIIFgjCCA2oCCQD7TLSQ/uU4AjANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMC
4y34NPO08tUuRauZvhejBWLlv1yC6UID0rLdkzjFd2x0hn326r3xaPMsD7BMZVXy
................................................................
O6dZxMeQwKIuDy1lQPTyleDIdKTSTX55/Dug7ey3/Ayl7Bw63H9rlEtKy8VONJrl
9G1sJf9MoktA9uPfMk0EU9B0CZzUUQ==
-----END CERTIFICATE-----
Run Code Online (Sandbox Code Playgroud)
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)

Run Code Online (Sandbox Code Playgroud)

你知道如何解决这个问题吗?

Pau*_*rer 9

load_pem_x509_certificate需要bytes,而不是字符串。在 Python 2.7 中,这种区别是无关紧要的,但在 3.x 中,您必须首先将其编码为字节。由于您正在从文件中读取此内容,因此最好的解决方案是将您的open调用更改为使用rb(读取二进制)作为模式,然后将certificate_file.read()返回字节。

  • 如果你只想将字符串编码为字节,你可以使用 `your_string.encode('utf-8')` (例如[这个问题在这里](/sf/ask/530980481/ -将字符串转换为python-3中的字节)) (5认同)