2015-05-07 15 views
10

Próbuję użyć połączyć się z innej strony przy użyciu Python 3 moduł asyncio i uzyskać ten błąd:Co oznacza "SSLError: [SSL] PEM lib (_ssl.c: 2532)" oznacza korzystanie z biblioteki Python ssl?

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

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

Pytanie jest tylko to, co znaczy błąd. Mój certyfikat jest poprawny, plik klucza (certyfikat CA) może nie być.

+0

Wspomniałeś, że kluczowy plik może nie być poprawny. Ładowanie certyfikatu nie powiedzie się, jeśli certyfikat (klucz publiczny) nie zostanie przesłany z odpowiednim plikiem klucza prywatnego. – Prabhu

+0

Masz 'keyfile = ca_cert', co wydaje się być nieprawidłowe (lub wybrałeś okropne nazwy zmiennych). Czy twój 'ca_cert' naprawdę zawiera klucz prywatny? – larsks

+0

@larsks Jak wybór strasznych nazw zmiennych może powodować błędy w kodzie? Wszelkie sugestie (lub konwencje) dotyczące ich nazwy? Plik ca_cert zaczyna się od '----- BEGIN CERTIFICATE -----', co wydaje się być prawidłowym zaszyfrowanym kluczem, a kończy się znakiem '----- END CERTIFICATE -----'. Czy nagłówek i stopka mówią coś innego? – sargas

Odpowiedz

14

Zakładając, że wersja 3.4 jest używany:

Patrz: https://github.com/python/cpython/blob/3.4/Modules/_ssl.c#L2529-L2535

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; 
} 

Co ona mówi, że SSL_CTX_check_private_key powiodło; w ten sposób klucz prywatny nie jest poprawny.

+0

Uzgodnione. Poszedłeś do źródła i znalazłeś właściwą odpowiedź. –

+0

Przeczytałem to wcześniej, ale nie miałem pojęcia, co to znaczy. Myślę, że używa on _openssl_ (na systemach uniksowych) i zgłaszania błędu, który dostał na poziomie systemu. To wyjaśnia, dlaczego błąd generowałby się z tej linii w źródle, prawda? – sargas

8

W kodzie, dzwonisz:

sslcontext.load_cert_chain(cert, keyfile=ca_cert) 

Z documentation:

Load a private key and the corresponding certificate. The certfile string must be the path to a single file in PEM format containing the certificate as well as any number of CA certificates needed to establish the certificate’s authenticity. The keyfile string, if present, must point to a file containing the private key in. Otherwise the private key will be taken from certfile as well. See the discussion of Certificates for more information on how the certificate is stored in the certfile.

Na podstawie nazwy argumentów w swojej przykład, wygląda na to jesteś przejazdem certyfikatu CA do argumentu keyfile. Jest to niepoprawne, musisz podać klucz prywatny, który został użyty do wygenerowania lokalnego certyfikatu (w przeciwnym razie klient nie będzie mógł użyć twojego certyfikatu). Plik klucza prywatnego będzie wyglądać następująco:

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

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

Trzeba tylko certyfikat CA jeśli próbują zweryfikować ważność certyfikatów SSL, które zostały podpisane przez tego certyfikatu. W takim przypadku prawdopodobnie użyjesz SSLContext.load_verify_locations() do załadowania certyfikatu CA (chociaż ostatnio nie pracowałem z modułem SSL, więc nie wierz mi w tym punkcie).