2016-06-26 6 views
3

Ich habe einen öffentlichen RSA-Schlüssel und ein signiertes X509-Zertifikat. Wie kann ich überprüfen, ob der Schlüssel das Zertifikat signiert hat? (Mein Beispiel geschieht, ein selbst signiertes Zertifikat sein.)Signatur auf X509-Zertifikat in Python überprüfen

Hier ist, was ich tue jetzt:

generieren selbst signiertes Zertifikat und konvertieren zu DER-Codierung mit openssl cli:

(I‘ m DIE in meiner realen Anwendung erwartet)

openssl req -x509 -newkey rsa:2048 -keyout selfsigned.key -nodes -out selfsigned.cert -sha256 -days 1000 
openssl x509 -outform der -in selfsigned.cert -out self.der 

Decode es zu einer Crypto.Util.asn1.DerSequence Instanz.

>>> from Crypto.Util.asn1 import DerSequence 
>>> from Crypto.PublicKey import RSA 
>>> der = open('self.der').read() 
>>> cert = DerSequence() 
>>> cert.decode(der) 
905L 
>>> # according to RFC5280, this is a 3-length sequence: 
>>> # tbsCertificate, signatureAlgorithm, signatureValue 
>>> # "tbs" == "to be signed" 
>>> len(cert) 
3 

Dann ziehe ich den öffentlichen RSA-Schlüssel aus:

>>> tbscert = DerSequence() 
>>> tbscert.decode(cert[0]) 
>>> subjectPublicKeyInfo = tbscert[6] 
>>> rsa_key = RSA.importKey(subjectPublicKeyInfo) 
>>> >>> rsa_key 
<_RSAobj @0x7fb27287d128 n(2048),e> 

Dann ziehe ich die Unterschrift aus

Das ist sehr ärgerlich. Ich benutze eine andere Bibliothek, um den DER erneut zu decodieren, weil dieser mir eine etwas bequemere Darstellung der "Bitstring" -Codierung des Signaturwerts gibt. Für den Moment kopiere ich und füge die Basis-2-String-Repräsentation des Wertes in int() ein, um eine long zu erhalten (was die RSA.verify()-Methode erwartet).

>>> from pyasn1_modules import rfc2437,rfc2459 
>>> from pyasn1.codec.der import decoder 
>>> cert2,rest = decoder.decode(der, asn1Spec=rfc2459.Certificate()) 
>>> sig_bits = cert2.getComponentByName("signatureValue") 
>>> sig_bits 
BitString("'10101110101100111010100000111001000110111111101001110000100111110111011111111110011010110101001001110110111011011001110001010000111001001001110111001110011101000000100000001100001101000111000110010100110101000110111101110001011011001001100011110011010101011100000001010111101110111001110011010011110101101001110101110100011111011111110001110001110100000110110100010000001010111010000100101110101001110000111001100010011110110100101001010000101001110101101111100111001111000010111001110000000101000000011110011110000110000101101101110110101101110101011110101111111000101011001000010000110100111111001011111100110011011011001001111110000000110100000001101000011010010100001100110100001001000111001011111100000011000101001100001010101001111000001010100101010101000100001000100011101111100101010010001111001110100001011110101100010111001010100010001011100000100101110001011101100010010111100010111110010010110111111100100100101010010000000010001011111110011000011000101000001000000000000011111101110010101100100000010111111110101000110010101111100101011101000010010110101000101101110001001101101000110101110011101011111100010000101001111011100100100010101001011011110001110000000000010011011111011110100000111001100010100000100001101111110010000111100110110110000001010010110011010111100101110101000001111001010011101001101101101101011000100010011110000101010110111011100010100011110101100110101011010111000011111000001111111111000101101101011110010111100101011100010000111011101101010101001011101101111011001001110000010011001111010001011110000011001011000110100011100000100100111000111100000010000001001001010001100000010011110100000111010010100001101001111111001111110111010001101010110100001100111010101000010000101000000111100001001001000100011100110010110101001110111101000101101011011100000010010000100111001100001110010101000100000010010111110001100011110010000100001000101100011000011000110010110011100010100010111011011111111010000001001100000100011010000000110111100111010101001110101000011111011000100010111101100110100010101111000110111110'B") 
>>> bit_string = '10101110101100111010100000111001000110111111101001110000100111110111011111111110011010110101001001110110111011011001110001010000111001001001110111001110011101000000100000001100001101000111000110010100110101000110111101110001011011001001100011110011010101011100000001010111101110111001110011010011110101101001110101110100011111011111110001110001110100000110110100010000001010111010000100101110101001110000111001100010011110110100101001010000101001110101101111100111001111000010111001110000000101000000011110011110000110000101101101110110101101110101011110101111111000101011001000010000110100111111001011111100110011011011001001111110000000110100000001101000011010010100001100110100001001000111001011111100000011000101001100001010101001111000001010100101010101000100001000100011101111100101010010001111001110100001011110101100010111001010100010001011100000100101110001011101100010010111100010111110010010110111111100100100101010010000000010001011111110011000011000101000001000000000000011111101110010101100100000010111111110101000110010101111100101011101000010010110101000101101110001001101101000110101110011101011111100010000101001111011100100100010101001011011110001110000000000010011011111011110100000111001100010100000100001101111110010000111100110110110000001010010110011010111100101110101000001111001010011101001101101101101011000100010011110000101010110111011100010100011110101100110101011010111000011111000001111111111000101101101011110010111100101011100010000111011101101010101001011101101111011001001110000010011001111010001011110000011001011000110100011100000100100111000111100000010000001001001010001100000010011110100000111010010100001101001111111001111110111010001101010110100001100111010101000010000101000000111100001001001000100011100110010110101001110111101000101101011011100000010010000100111001100001110010101000100000010010111110001100011110010000100001000101100011000011000110010110011100010100010111011011111111010000001001100000100011010000000110111100111010101001110101000011111011000100010111101100110100010101111000110111110' 
>>> len(bit_string) 
2048 
>>> sig_long = int(bit_string, 2) 
22054057292543290008991218833668878365914778519473463062473060546762899555976103489048033910135613221569150796460758806399269198735780309519101363051388009338597879536630494212385605300708879019160215628821483902624509955250980351374010304684207884550324020859785789812498991361733361061223150200173076263554090698006436248180914014712709890577579243572383188197634606581121383593473899061397708617253275982314075801792358481980896751043809539358665686019958496887281091997170247998458556812030465091755579654010246474389968142047627934047174316731806191431717418170761689395728146445291177267566370799362894264463806L 

Dann berechnen ich die SHA256 Hash-Wert des „signiertes Zertifikat zu“:

>>> import Crypto.Hash.SHA256 
>>> comp_hash = Crypto.Hash.SHA256.new(cert[0]).digest() 
>>> comp_hash 
'\xa3t\x84\xd6\xf5\xfe\x16\xb9\xdb(&\x12\xb3m^+\x94\xa7bZ\xf9s\xf7\xbay\xa1j\xa3Y\xea\xa8\x7f' 

Dann wird die verify() Methode sagt mir die Signatur nicht übereinstimmt.

>>> rsa_key.verify(comp_hash, (sig_long, None)) 
False 

Ich hoffe, es gibt einen besseren Weg (dies ist nicht einmal arbeiten), aber ich habe Stunden damit verbracht, bei PyCrypto und pyopenssl suchen und haben es nicht gefunden.

Bearbeitungen

Diese ähnliche S.O. Frage von vor ein paar Jahren hat keine Antwort: Verify SSL/X.509 certificate is signed by another certificate

Antwort

1

Ich denke, ein Weg, um dies zu erreichen, ist eine X509StoreContext mit nur einem Zertifikat entsprechend dem öffentlichen Schlüssel, den ich überprüfen möchten, zu erstellen.

>>> from OpenSSL import crypto 
>>> x509_self_signed # already loaded 
<OpenSSL.crypto.X509 object at 0x7fcc4049c9b0> 
>>> cert_store = crypto.X509Store() 
>>> cert_store.add_cert(x509_self_signed) 
>>> store_ctx = crypto.X509StoreContext(cert_store, x509_self_signed) 
>>> store_ctx.verify_certificate() 
>>> #^that raises an exception if it fails to verify 

verify_certificate() wurde nur etwas mehr als vor einem Jahr, so zu pyopenssl hinzugefügt vielleicht deshalb ist es zu finden war schwer zu ... https://github.com/pyca/pyopenssl/pull/155

Verwandte Themen