2016-06-26 8 views
3

私はRSA公開鍵と署名付きX509証明書を持っています。鍵が証明書に署名したことを確認するにはどうすればよいですか? (私の例では、自己署名証明書であることを起こる)PythonのX509証明書の署名を確認する

ここで私が今やっているものです:

は、自己署名証明書を生成し、opensslのCLIでDERエンコーディングに変換します。

(I」私の実際のアプリケーションでDERを期待メートル)

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 

Crypto.Util.asn1.DerSequenceインスタンスにそれをデコードします。

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

は、その後、私は外にRSA公開鍵を引く:

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

それから私は、これは非常に迷惑です

署名を引き出します。私はDERをもう一度解読するために別のライブラリを使用しています。これは、この値が署名値の "ビット列"エンコーディングを少し便利に表現できるからです。今のところ、値の基数2の文字列表現をコピーしてint()に貼り付けて、longRSA.verify()メソッドが期待するもの)を取得します。

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

それから私は、「署名する証明書」のSHA256ハッシュを計算する:

>>> 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' 

その後verify()方法は、署名が一致していないと言われます。

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

私はより良い方法は、(これも動作しません)があります願っていますが、私はPyCryptoとPyOpenSSLを見て時間を費やしてきたし、それを発見していません。

編集

この類似したS.O.数年前の質問には答えがありません:Verify SSL/X.509 certificate is signed by another certificate

答えて

1

これを達成するには、確認したい公開鍵に対応する証明書が1つだけ含まれているX509StoreContextを作成することをお勧めします。

>>> 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()は...それを見つけるのは難しかった理由ので、多分それはだ、少しだけ1年以上前PyOpenSSLに追加された https://github.com/pyca/pyopenssl/pull/155

関連する問題