2009-12-08 66 views
2

我试图实现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算法产生的签名。任何关于这个映射的想法?

回答

1

这些是不同的操作。在Python中,您需要使用hashAndSign。默认情况是SHA1哈希。

+0

这就是现货!非常感谢。 – Jayesh 2009-12-08 16:11:34

1

Keyczar应该可以在App Engine上正常工作,并且可以在Java和Python中使用。