我正在尝试实现一个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值。但是没有人能用pkcs1-sha1算法验证tlslite生成的签名。对这个映射有什么想法吗?
发布于 2009-12-08 23:21:35
这些是不同的操作。在Python中,您需要使用hashAndSign。默认值恰好是SHA1散列。
发布于 2009-12-10 19:36:46
Keyczar应该可以在App Engine上很好地工作,并且有Java和Python两种风格。
https://stackoverflow.com/questions/1867355
复制相似问题