2013-06-03 8 views
14

Come posso decodificare un certificato pem-codificato (base64) con Python? Per esempio questo qui da github.com:Come posso decodificare un certificato SSL usando python?

-----BEGIN CERTIFICATE----- 
MIIHKjCCBhKgAwIBAgIQDnd2il0H8OV5WcoqnVCCtTANBgkqhkiG9w0BAQUFADBp 
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 
d3cuZGlnaWNlcnQuY29tMSgwJgYDVQQDEx9EaWdpQ2VydCBIaWdoIEFzc3VyYW5j 
ZSBFViBDQS0xMB4XDTExMDUyNzAwMDAwMFoXDTEzMDcyOTEyMDAwMFowgcoxHTAb 
BgNVBA8MFFByaXZhdGUgT3JnYW5pemF0aW9uMRMwEQYLKwYBBAGCNzwCAQMTAlVT 
MRswGQYLKwYBBAGCNzwCAQITCkNhbGlmb3JuaWExETAPBgNVBAUTCEMzMjY4MTAy 
MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2Fu 
IEZyYW5jaXNjbzEVMBMGA1UEChMMR2l0SHViLCBJbmMuMRMwEQYDVQQDEwpnaXRo 
dWIuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA7dOJw11wcgnz 
M08acnTZtlqVULtoYZ/3+x8Z4doEMa8VfBp/+XOvHeVDK1YJAEVpSujEW9/Cd1JR 
GVvRK9k5ZTagMhkcQXP7MrI9n5jsglsLN2Q5LLcQg3LN8OokS/rZlC7DhRU5qTr2 
iNr0J4mmlU+EojdOfCV4OsmDbQIXlXh9R6hVg+4TyBkaszzxX/47AuGF+xFmqwld 
n0xD8MckXilyKM7UdWhPJHIprjko/N+NT02Dc3QMbxGbp91i3v/i6xfm/wy/wC0x 
O9ZZovLdh0pIe20zERRNNJ8yOPbIGZ3xtj3FRu9RC4rGM+1IYcQdFxu9fLZn6TnP 
pVKACvTqzQIDAQABo4IDajCCA2YwHwYDVR0jBBgwFoAUTFjLJfBBT1L0KMiBQ5um 
qKDmkuUwHQYDVR0OBBYEFIfRjxlu5IdvU4x3kQdQ36O/VUcgMCUGA1UdEQQeMByC 
CmdpdGh1Yi5jb22CDnd3dy5naXRodWIuY29tMIGBBggrBgEFBQcBAQR1MHMwJAYI 
KwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBLBggrBgEFBQcwAoY/ 
aHR0cDovL3d3dy5kaWdpY2VydC5jb20vQ0FDZXJ0cy9EaWdpQ2VydEhpZ2hBc3N1 
cmFuY2VFVkNBLTEuY3J0MAwGA1UdEwEB/wQCMAAwYQYDVR0fBFowWDAqoCigJoYk 
aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL2V2MjAwOWEuY3JsMCqgKKAmhiRodHRw 
Oi8vY3JsNC5kaWdpY2VydC5jb20vZXYyMDA5YS5jcmwwggHEBgNVHSAEggG7MIIB 
tzCCAbMGCWCGSAGG/WwCATCCAaQwOgYIKwYBBQUHAgEWLmh0dHA6Ly93d3cuZGln 
aWNlcnQuY29tL3NzbC1jcHMtcmVwb3NpdG9yeS5odG0wggFkBggrBgEFBQcCAjCC 
AVYeggFSAEEAbgB5ACAAdQBzAGUAIABvAGYAIAB0AGgAaQBzACAAQwBlAHIAdABp 
AGYAaQBjAGEAdABlACAAYwBvAG4AcwB0AGkAdAB1AHQAZQBzACAAYQBjAGMAZQBw 
AHQAYQBuAGMAZQAgAG8AZgAgAHQAaABlACAARABpAGcAaQBDAGUAcgB0ACAAQwBQ 
AC8AQwBQAFMAIABhAG4AZAAgAHQAaABlACAAUgBlAGwAeQBpAG4AZwAgAFAAYQBy 
AHQAeQAgAEEAZwByAGUAZQBtAGUAbgB0ACAAdwBoAGkAYwBoACAAbABpAG0AaQB0 
ACAAbABpAGEAYgBpAGwAaQB0AHkAIABhAG4AZAAgAGEAcgBlACAAaQBuAGMAbwBy 
AHAAbwByAGEAdABlAGQAIABoAGUAcgBlAGkAbgAgAGIAeQAgAHIAZQBmAGUAcgBl 
AG4AYwBlAC4wHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMBEGCWCGSAGG 
+EIBAQQEAwIGwDAOBgNVHQ8BAf8EBAMCBaAwDQYJKoZIhvcNAQEFBQADggEBABRS 
cR+GnW01Poa7ZhqLhZi5AEzLQrVG/AbnRDnI6FLYERQjs3KW6RSUni8AKPfVBEVA 
AMb0V0JC3gmJlxENFFxrvQv3GKNfZwLzCThjv8ESnTC6jqVUdFlTZ6EbUFsm2v0T 
flkXv0nvlH5FpP06STLwav+JjalhqaqblkbIHOAYHOb7gvQKq1KmyuhUItnbKj1a 
InuA6gcF1PnH8FNZX7t3ft6TcEFOI8t4eXnELurXZioY99HFfOISeIKNHeyCngGi 
5QK+eKG5WVjFTG9PpTG0SVtemB4uOPYZxDmiSvt5BbjyWeUmEnCtwOh1Ix8Y0Qvg 
n2Xkw9dJh1tybLEvrG8= 
-----END CERTIFICATE---- 

Secondo ssl-shopper dovrebbe essere qualcosa di simile:

Common Name: github.com 
Subject Alternative Names: github.com, www.github.com 
Organization: GitHub, Inc. 
Locality: San Francisco 
State: California 
Country: US 
Valid From: May 26, 2011 
Valid To: July 29, 2013 

Come posso ottenere questo testo in chiaro utilizzando Python?

+1

DO devi usare python? L'output di cmdline di openssl lo farà per te. – Joe

+0

Voglio ottenere alcune informazioni dal file di certificazione in un programma python, al volo. – puwei219

+0

potresti usare asn1crypto, pyOpenSSL, M2Crypto, crittografia, pacchetti pyasn1 python. Ecco [esempio di codice (in russo)] (http://ru.stackoverflow.com/a/464445/23044) – jfs

risposta

17

La libreria standard di Python, anche nell'ultima versione, non include nulla che possa decodificare i certificati X.509. Tuttavia, il pacchetto aggiuntivo cryptography supporta questo. Citando un example from the documentation:

>>> from cryptography import x509 
>>> from cryptography.hazmat.backends import default_backend 
>>> cert = x509.load_pem_x509_certificate(pem_data, default_backend()) 
>>> cert.serial_number 
2 

Un altro pacchetto add-on che potrebbe essere un'opzione è pyopenssl. Questo è un sottile involucro intorno all'AP OpenSSL C, il che significa che sarà possibile fare ciò che vuoi, ma aspettarti di passare un paio di giorni a strapparti i capelli alla documentazione.

Se non è possibile installare Python pacchetti aggiuntivi, ma si ha l'utilità openssl della riga di comando,

import subprocess 
cert_txt = subprocess.check_output(["openssl", "x509", "-text", "-noout", 
            "-in", certificate]) 

dovrebbe produrre più o meno le stesse cose che hai dalla tua utility web cert_txt.

Per inciso, la ragione per cui si esegue una decodifica di base64 diretta ti dà un gobbledygook binario è che ci sono due livelli di codifica qui. X.509 certificates sono strutture di dati ASN.1, serializzate nel formato X.690 DER e quindi, poiché DER è un formato binario, corazzato con base64 per facilitare il trasferimento dei file. (Molti standard in questo settore sono stati scritti negli anni Novanta quando non si poteva spedire in modo affidabile tutto tranne ASCII a sette bit.)

24

È possibile utilizzare i pacchetti pyasn1 e pyasn1_modules per analizzare questo tipo di dati. Ad esempio:

from pyasn1_modules import pem, rfc2459 
from pyasn1.codec.der import decoder 

substrate = pem.readPemFromFile(open('cert.pem')) 
cert = decoder.decode(substrate, asn1Spec=rfc2459.Certificate())[0] 
print(cert.prettyPrint()) 

Leggere i documenti per pyasn1 per il resto.