我試圖實現PKI驗證方案,其中消息字符串使用服務器上的私鑰簽名,簽名與消息字符串一起存儲在客戶端上。然後客戶端使用公鑰驗證簽名。跨Java和Python的PKI驗證
我的環境的限制是,服務器是Google App Engine,客戶端是Java程序。我使用了純Java和僅Python的PKI驗證解決方案,並讓它們工作,但是當在Python中執行一個操作而在Java中執行另一個操作時出現問題,這主要是由於密鑰文件格式限制和我對密碼學術語的理解有限。
最大的限制之一是GAE中的加密支持。唯一支持的庫是PyCrypto,並且該庫無法讀取以PEM,DER或X509格式存儲的公鑰/私鑰。據我所知,只有M2Crypto支持從這些文件中讀取數據,但它不能在GAE內部使用,因爲它是openssl的封裝,所以不是純粹的Python解決方案。即使我能找到一種方法將PEM/DER/X509中的公鑰/私鑰翻譯成PyCrypto能夠理解的格式,這對我而言也是如此。但我找不到任何辦法。那裏有任何想法?
我發現了一種可能的解決方案,形式爲tlslite。 tlslite可以從PEM文件讀取私鑰並創建簽名。這是代碼。
from tlslite.utils.cryptomath import bytesToBase64
from tlslite.utils.keyfactory import parsePEMKey
s = open('private.pem').read()
key = parsePEMKey(s)
doc = 'Sample text'
bytes = array('B')
bytes.fromstring(doc)
print bytesToBase64(key.sign(bytes))
我用來驗證簽名的相應Java代碼是。
String signAlgo = "SHA1WithRSAEncryption";
// read public key from public.der
byte[] encodedKey = new byte[294]; // shortcut hardcoding
getAssets().open("public.der").read(encodedKey);
// create public key object
X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(encodedKey);
KeyFactory kf = KeyFactory.getInstance("RSA");
PublicKey pk = kf.generatePublic(publicKeySpec);
// read signature (created by python code above)
byte[] encodedSig = new byte[345];
getAssets().open("signature.txt").read(encodedSig);
byte[] decodedSig = Base64.decodeBase64(encodedSig);
// Do verification
Signature verifyalg = Signature.getInstance(signAlgo);
verifyalg.initVerify(pk);
verifyalg.update(message.getBytes());
Log.d(TAG, "Verif : "+verifyalg.verify(decodedSig));
驗證失敗。
我懷疑tlslite是否使用不同的算法進行簽名創建,而不是java代碼所期望的。
所以我試圖找出答案。
在Python端
print key.getSigningAlgorithm()
給我
pkcs1-sha1
在Java方面,我試圖找到與此代碼所有支持的算法:
Set<String> algos = java.security.Security.getAlgorithms("Signature");
for(String algo : algos) {
Log.d(TAG, algo);
}
這給了我
MD4WithRSAEncryption
RSASSA-PSS
SHA1withDSA
SHA1withRSA/ISO9796-2
1.2.840.113549.1.1.10
SHA512withRSA/PSS
MD5withRSA/ISO9796-2
DSA
SHA512WithRSAEncryption
SHA224withRSA/PSS
NONEWITHDSA
SHA256withRSA/PSS
SHA224WithRSAEncryption
SHA256WithRSAEncryption
SHA1withRSA/PSS
SHA1WithRSAEncryption
SHA384withRSA/PSS
SHA384WithRSAEncryption
MD5WithRSAEncryption
我嘗試了Java端的所有SHA1值。但沒有人幫助驗證tlslite與pkcs1-sha1算法產生的簽名。任何關於這個映射的想法?
這就是現貨!非常感謝。 – Jayesh 2009-12-08 16:11:34