Java Python消息签名和验证

时间:2012-06-29 21:37:20

标签: java python compatibility digital-signature pycrypto

我的服务器是用Python编写的,我正在为这个服务器创建一个java客户端。

我正在使用以下方式签署消息(数据)

public static byte[] Sign(PrivateKey privateKey, byte[] data) throws Exception{
        System.out.println("Signing the key inside RSACrypto#Sign");
        Signature dsa = Signature.getInstance("SHA1withRSA");

        SecureRandom secureRandom =null;
        dsa.initSign(privateKey,secureRandom);
        dsa.update(data);
        return dsa.sign();
}

这将返回一个byteArray(名为signed_data),现在我使用Base64.encodeBase64对此签名进行编码,并使用以下方法将byteArray(名为my_byte_array)转换为字符串:

String str = new String(my_byte_array)

并将此字符串发送到服务器。

在服务器端,我收到此字符串,然后服务器使用以下命令验证签名:

publicKey.verify(str(data), (long(base64.b64decode(my_byte_array)),))

使用库http://gdata-python-client.googlecode.com/hg/pydocs/gdata.Crypto.PublicKey.RSA.html

当我尝试在两侧打印my_byte_array时它们是相同的,所以是signed_data和base64.b64decode(my_byte_array)

但是我收到了这个错误:

ValueError: invalid literal for long() with base 10: '\x8b\xa1\xbb\x19fO\xea\xe7\xa4B\xd4\xd2\xa1\xe3\xb9\xd0\x89n\xa2\xfe\xb5\xedsL\x02\xba\xad\x12!qjp\x0c%+Z\t\xa7\x12\x08\x90\xfaTk\xca\xd0\xae\xd8\xa9\xfa\xbb]>9\x1c\x80\xd0

据我所知,这个错误是因为Java将消息签名为byte而python期望它是Long。

有没有办法解决这个问题?

1 个答案:

答案 0 :(得分:1)

你实际上有两个问题。

第一个是 - 根据Java Cryptograpy Architecture API - SHA1withRSA 算法涉及PKCS#1 v1.5填充。在Python端,您必须使用相同的填充方案来验证签名;可以使用PyCrypto的PKCS#1 v1.5签名模块(Crypto.Signature.PKCS1_v1_5)来实现。

第二个问题是你指出的问题:RSA PyCrypto对象的verify方法 奇怪地要求签名被编码为整数。但是,通过使用上面提到的模块,问题将消失,因为它接受字节字符串。