java - 跨 Java 和 Python 的 PKI 验证

标签 java python google-app-engine cryptography

我正在尝试实现 PKI 验证方案,其中消息字符串在服务器上使用私钥签名,签名与消息字符串一起存储在客户端上。然后客户端使用公钥验证签名。

我的环境限制是,服务器是Google App Engine,客户端是Java程序。我玩过 PKI 验证的纯 Java 和纯 Python 解决方案并让它们工作,但是当在 Python 中执行一个操作而在 Java 中执行另一个操作时会出现问题,这主要是由于 key 文件格式限制和我对密码学术语的有限理解.

最大的限制之一是 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 算法生成的签名。对这个映射有什么想法吗?

最佳答案

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

关于java - 跨 Java 和 Python 的 PKI 验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1867355/

相关文章:

java - 适用于 Google App Engine/J 的 BaaS

java - 类似的接口(interface)问题

python - 在Python的while循环条件中分配变量?

java - 如何在 NetBeans 8 上使用旧版本的 Java(不是默认版本)和 Maven 项目

python - 部署 Django 项目

python - 如何让 gevent 应用程序在出现异常后立即退出?

java - 在 android 中使用谷歌应用引擎存储和检索图像?

java - 使用 'NOT IN' 的备用逻辑的 Google App Engine JDO 查询

java - Java如何确定操作系统名称?

java - ResultSet 转 CSV 格式字符串