我试图实现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