簡體   English   中英

“SSLError: [SSL] PEM lib (_ssl.c:2532)”是什么意思使用 Python ssl 庫?

[英]What does "SSLError: [SSL] PEM lib (_ssl.c:2532)" mean using the Python ssl library?

我正在嘗試使用 Python 3 asyncio 模塊連接到另一方並收到此錯誤:

     36     sslcontext = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
---> 37     sslcontext.load_cert_chain(cert, keyfile=ca_cert)
     38

SSLError: [SSL] PEM lib (_ssl.c:2532)

問題是錯誤的含義。 我的證書是正確的,密鑰文件(CA 證書)可能不正確。

假設正在使用 3.6 版:

參見: https ://github.com/python/cpython/blob/3.6/Modules/_ssl.c#L3523-L3534

 PySSL_BEGIN_ALLOW_THREADS_S(pw_info.thread_state);
 r = SSL_CTX_check_private_key(self->ctx);
 PySSL_END_ALLOW_THREADS_S(pw_info.thread_state);
 if (r != 1) { 
    _setSSLError(NULL, 0, __FILE__, __LINE__);
    goto error;
 }

它的意思是SSL_CTX_check_private_key失敗; 因此,私鑰不正確。

參考可能的版本:

在您的代碼中,您正在調用:

sslcontext.load_cert_chain(cert, keyfile=ca_cert)

文檔中:

加載私鑰和相應的證書。 certfile 字符串必須是 PEM 格式的單個文件的路徑,該文件包含證書以及建立證書真實性所需的任意數量的 CA 證書。 keyfile 字符串(如果存在)必須指向包含私鑰的文件。否則私鑰也將從 certfile 中獲取。 有關證書如何存儲在 certfile 中的更多信息,請參閱證書的討論。

根據示例中的參數名稱,您似乎正在將 CA 證書傳遞給keyfile參數。 這是不正確的,您需要傳入用於生成本地證書的私鑰(否則客戶端無法使用您的證書)。 私鑰文件如下所示:

-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,9BA4973008F0A0B36FBE1426C198DD1B

...data...
-----END RSA PRIVATE KEY-----

如果您嘗試驗證已由該證書簽名的 SSL 證書的有效性,則只需要 CA 證書。 在這種情況下,您可能會使用SSLContext.load_verify_locations()來加載 CA 證書(盡管我最近沒有使用 SSL 模塊,所以不要相信我的話)。

該錯誤表示缺少私鑰文件。 在 openssl shell 中生成密鑰對: openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365

啟動 Python SSL 服務器:

from http.server import HTTPServer, 
             SimpleHTTPRequestHandler

import ssl

httpd = HTTPServer(('localhost', 4443), 
                           SimpleHTTPRequestHandler)

httpd.socket = ssl.wrap_socket(httpd.socket, 
                 certfile='/tmp/cert.pem',keyfile='
                           /tmp/key.pem', server_side=True)

httpd.serve_forever()

(我們使用端口 4443 以便我可以以普通用戶身份運行測試;通常的端口 443 需要 root 權限)。

就我而言,此錯誤意味着我的證書具有錯誤的文件擴展名。 我必須使用以下命令將我的cert.der文件轉換為cert.pem文件:

openssl x509 -inform der -in cert.der -out cert.pem 

在使用 openssl 生成受密碼保護的自簽名證書時,我遇到了類似的問題,我得到以下輸出:

ontext.load_cert_chain(certfile= certificate_private, keyfile= certificate)
ssl.SSLError: [SSL] PEM lib (_ssl.c:4012)

在閱讀了兩次以了​​解load_cert_chain上的文檔后,我想出了以下解決方案:

import ssl
    
context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
context.load_cert_chain(certfile= certificate_private, keyfile= certificate_key, password= certificate_password)

connection = http.client.HTTPSConnection(host, port=443, context=context)
connection.request(method="POST", url=request_url, headers=request_headers, body=json.dumps(request_body_dict))
response = connection.getresponse()

certfile 是cert.pem
密鑰文件是key.pem
並且密碼是我在生成類似於此答案中所述的自簽名證書時使用的密碼。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM