2011-07-11 4 views
0

- dsa公開鍵を保持したx509証明書を使用して署名付きメッセージを検証しようとしています。 x509証明書は、PKCS7エンコーディングでSAPシステムによって提供され、opensslを使用してPEMで変換した後、内容を読み取ることができます(openssl x509 -in sapcert.pem -inform pem -text) dsaEncryptionで公開鍵を保持しています私にDSAパラメータy(pub)、p、q、gを示しています。python/m2cryptoのDSA公開鍵とのdsawithSha1署名付きメッセージの確認に失敗しました

私はM2Crypto x509クラスでDSA実装を見つけられなかったので、自分でDSA公開鍵を構築しようとしました。そのため、私はMyCryptoにパッチを当てて(How do I create a M2Crypto DSA object given parameters and key values?参照)、コンパイルして、DSA.pub_key_from_params(p、q、g、y)を取得して、証明書にあるパラメータを使用してDSA公開鍵を構築しました。 これまではすべて正常に動作します。 (ユニットテストはエラーなしで実行されましたが)。

2番目のステップでは、URLパラメータとしてsignedMessage(seckeyという名前)を受け取って、それをデコードした後(base64)、適切なDER文字列を取得しました。openssl(openssl ans1parse -in seckey -inform der )。 opensslからの出力には、私が検証しようとしているSHA1で符号化されたmessagedigest(つまり、signedMessageが適切に提供されたことを確かめることができます)である署名付きmessageDigestが見えます。私はdsaWithSHA1署名文字列を見ることができますが、署名付きメッセージの検証に必要なrとsの値を保持しているようです(M2Crypto: verifying DSA signatures参照)

この時点で、signedMessageを数日間確認しようとしました今私は、私を助けることができる凍結検査専門家がいることを願っています。私はたくさん試してみましたが、代わりにpyCryptoのlibを試しました。

SHA1 MessageDigestとrとsの値をM2Crypto.DSA.verify関数に渡そうとしましたが、失敗したためsignedMessageまたはその一部を渡す必要がありました。 (Javaのフォーラムでは、私は上の署名を計算について多少SAPが提供するsignedMessagesとtheresのを確認することについてのいくつかの記事見つけ、「署名属性のDERエンコーディング を。」?)

ここに私のサンプルコードがあります:

# -*- coding: iso-8859-1 -*- 

import M2Crypto 
import urllib 
import base64 
from Crypto.Util import asn1 
from M2Crypto import m2 
import sha 

# the certificate 
cert = """subject=/C=DE/O=SAP Trust Community/OU=SAP Web AS/OU=I0020154766/CN=RE2 
issuer=/C=DE/O=SAP Trust Community/OU=SAP Web AS/OU=I0020154766/CN=RE2 
-----BEGIN CERTIFICATE----- 
MIICMDCCAe8CAQAwCQYHKoZIzjgEAzBkMQswCQYDVQQGEwJERTEcMBoGA1UEChMT 
U0FQIFRydXN0IENvbW11bml0eTETMBEGA1UECxMKU0FQIFdlYiBBUzEUMBIGA1UE 
CxMLSTAwMjAxNTQ3NjYxDDAKBgNVBAMTA1JFMjAeFw05NzEwMDEwMDAwMDBaFw0z 
ODAxMDEwMDAwMDBaMGQxCzAJBgNVBAYTAkRFMRwwGgYDVQQKExNTQVAgVHJ1c3Qg 
Q29tbXVuaXR5MRMwEQYDVQQLEwpTQVAgV2ViIEFTMRQwEgYDVQQLEwtJMDAyMDE1 
NDc2NjEMMAoGA1UEAxMDUkUyMIHyMIGpBgcqhkjOOAQBMIGdAkEA//8x1Bqn4a00 
FKr9CTwPPskxy0yrx7iU6T4vza4wW93Mo2d/IYTZNAxFqhrm+fIUrEp5fxIpYRmJ 
rKL2qRCUmQIVANrcsXlFvrXH455gM69vKZebhQZfAkEAmYzXTzHYwvqKEM46FvQX 
yC5O+JInwgk7Dac7gqGAkkhCS1aII4Vkc9kIEx3GFLD2mx4+yJuMQ8pQ4wz4FkfB 
JANEAAJBAI1em/0owxMTEP+akz56BovQ7Q6LiqUmVLLxJcjDozjI+5z6IrAPtub2 
veLXPdghDHcHB5jHKoqT4JHpqRc+uhIwCQYHKoZIzjgEAwMwADAtAhRm2jqiMWL+ 
26mA7HdKfZdkawMuYQIVAMekXdAT4wbyrb5/yFtuIPjCBfpr 
-----END CERTIFICATE----- 

""" 
f = open('sapcert.pem', 'w') 
f.write(cert) 
f.close() 

# now you can see it content with openssl 
# openssl x509 -in sapcert.pem -inform pem -text 


# this is the signedMessage 
secKey = "MIIBSwYJKoZIhvcNAQcCoIIBPDCCATgCAQExCzAJBgUrDgMCGgUAMAsGCSqGSIb3DQEHATGCARcwggETAgEBMGkwZDELMAkGA1UEBhMCREUxHDAaBgNVBAoTE1NBUCBUcnVzdCBDb21tdW5pdHkxEzARBgNVBAsTClNBUCBXZWIgQVMxFDASBgNVBAsTC0kwMDIwMTU0NzY2MQwwCgYDVQQDEwNSRTICAQAwCQYFKw4DAhoFAKBdMBgGCSqGSIb3DQEJAzELBgkqhkiG9w0BBwEwHAYJKoZIhvcNAQkFMQ8XDTExMDUyNjE1MzAyNVowIwYJKoZIhvcNAQkEMRYEFPelg4iVtaKORpuFxUvgo23Du7%2BtMAkGByqGSM44BAMELjAsAhQ46oCNmzZArb5yOFSYGY0hWu8dZwIUT35hPccJ6B9HIsOE0u8LwYZaFNk%3D" 
secKey = urllib.unquote(secKey) 
secKey64 = base64.b64decode(secKey) 
# now you can save it as a DER encoded file 
f = open('seckey.der', 'wb') 
f.write(secKey64) 
f.close() 
# you can pass it to openssl to see the the content 
# openssl asn1parse -in seckey.der -inform der 


# here is the sha1 encoded messagedigest I had to verify 
hashstr = "ZS4DDB9616BA031C40E1008003AC100097dCN%3DRE2,OU%3DI0020154766,OU%3DSAPWebAS,O%3DSAPTrustCommunity,C%3DDE20110526173025" 
osha1=M2Crypto.EVP.MessageDigest('sha1') 
osha1.update(hashstr) 
sha1_md = osha1.digest() 
print sha1_md.encode('hex') 

# now i build a DSA key with the params found in the certificate 

pub="8d5e9bfd28c3131310ff9a933e7a068bd0ed0e8b8aa52654b2f125c8c3a338c8fb9cfa22b00fb6e6f6bde2d73dd8210c77070798c72a8a93e091e9a9173eba12" 
p="ffff31d41aa7e1ad3414aafd093c0f3ec931cb4cabc7b894e93e2fcdae305bddcca3677f2184d9340c45aa1ae6f9f214ac4a797f1229611989aca2f6a9109499" 
q="dadcb17945beb5c7e39e6033af6f29979b85065f" 
g="998cd74f31d8c2fa8a10ce3a16f417c82e4ef89227c2093b0da73b82a1809248424b568823856473d908131dc614b0f69b1e3ec89b8c43ca50e30cf81647c124" 


pub1 = M2Crypto.m2.bn_to_mpi(M2Crypto.m2.hex_to_bn(pub)) 
p1 = M2Crypto.m2.bn_to_mpi(M2Crypto.m2.hex_to_bn(p)) 
q1 = M2Crypto.m2.bn_to_mpi(M2Crypto.m2.hex_to_bn(q)) 
g1 = M2Crypto.m2.bn_to_mpi(M2Crypto.m2.hex_to_bn(g)) 

# this function is available after patching und compiling M2Crypto 
# https://bugzilla.osafoundation.org/attachment.cgi?id=5700 
dsa1 = M2Crypto.DSA.pub_key_from_params(p1, q1, g1, pub1) 
print dsa1.check_key() 

# this seems to be the signature-values r and s in seckey.der 
asn_hex = "302C021438EA808D9B3640ADBE72385498198D215AEF1D6702144F7E613DC709E81F4722C384D2EF0BC1865A14D9" 

r = asn_hex[8:48] 
s = asn_hex[52:] 
r1 = M2Crypto.m2.bn_to_mpi(M2Crypto.m2.hex_to_bn(r)) 
s1 = M2Crypto.m2.bn_to_mpi(M2Crypto.m2.hex_to_bn(s)) 

# but this fails 
v = dsa1.verify(sha1_md, r1, s1) 
print v 

# this too 
sk = M2Crypto.m2.bn_to_mpi(M2Crypto.m2.bin_to_bn(secKey64)) 
v = dsa1.verify(sk, r1, s1) 
print v 

適切なdsawithsha1署名検証を行う方法を知っている人はいますか?助けてください!あなたのサンプルコードでseckey64の名前は何 よろしく、 ファルコ

答えて

0

実際CMSからのSignedData構造です。

これには、署名時刻とメッセージダイジェストという2つの「署名属性」が含まれています。これを署名として検証するには、少なくとも1つの署名付き属性が存在する場合に適用されるRFCの規則に従う必要があります。

元のデータのメッセージダイジェストはmessage-digest属性に含まれているため、最初にバイトごとに属性の値バイトと計算を比較する必要があります。

これらが等しい場合、SignerInfo構造の適切なフィールドから署名値を抽出します。最後に、DSA署名検証のもう1つの入力として機能するSHA-1メッセージダイジェストは、SignerInfoの署名付き属性の生のコード化で計算されます。 M2CryptoにSignedData(PKCS#7と呼ばれることが多い)の組み込みサポートがあるかどうかはわかりませんが、pyOpenSSLはそれをサポートしているはずですので、M2Cryptoがデッドエンドにつながる場合は試してみてください。

+0

ご回答いただきありがとうございました。ご返信ありがとうございます。 openssl 1.0.0の新しい実装されたcms関数へのopenssl呼び出しを使用して署名を検証する方法を見つけました。私がもっと時間があれば、もっとpythonicな解決法を見つけようとします。私はあなたの説明と提案がこれに非常に役立つでしょう。私はこのpyOpenSSLまたはM2Cryptoを行う方法を見つけたらあなたに通知します。ありがとう、ファルコ –

関連する問題