Java 带有RSA签名的SHA256在各种Android设备上返回不同的输出

Java 带有RSA签名的SHA256在各种Android设备上返回不同的输出,java,android,rsa,digital-signature,Java,Android,Rsa,Digital Signature,我正在开发一个Android应用程序,我需要用于数据认证 在每个安卓设备上,我都可以对数据签名并验证其签名。但是,给定要签名的特定数据块、特定模数、特定私有指数和特定公共指数,签名的输出会有所不同,具体取决于设备。我确实尝试了很多设备,我获得了Android 3.2和3.2.1的相同签名,但Android 2.2.x设备的签名有所不同 我从之前在java项目中使用RSA的KeyFactory生成的常量字段计算这些签名。密钥大小为2048bit 下面是我用来进行签名和验证的代码的引用 public

我正在开发一个Android应用程序,我需要用于数据认证

在每个安卓设备上,我都可以对数据签名并验证其签名。但是,给定要签名的特定数据块、特定模数、特定私有指数和特定公共指数,签名的输出会有所不同,具体取决于设备。我确实尝试了很多设备,我获得了Android 3.2和3.2.1的相同签名,但Android 2.2.x设备的签名有所不同

我从之前在java项目中使用RSA的
KeyFactory
生成的常量字段计算这些签名。密钥大小为2048bit

下面是我用来进行签名和验证的代码的引用

public byte[]signData(byte[]data,PrivateKey-PrivateKey)抛出。。。{
Signature=Signature.getInstance(“SHA256withRSA”);
signature.initSign(私钥);
签名。更新(数据);
返回签名。sign();
}
公共布尔验证数据(字节[]数据,字节[]sigBytes,公钥公钥)抛出。。。{
Signature=Signature.getInstance(“SHA256withRSA”);
签名。初始化验证(公钥);
签名。更新(数据);
返回签名。验证(sigBytes);
}
如果我没有弄错的话,使用SHA256和RSA的签名是确定性的。那么,我如何解释这种行为呢?另一个有趣的问题是,我如何让它跨设备工作,也就是说,签名是相同的,不知道我使用哪种设备


先谢谢你,弗兰克

是的,
SHA256withRSA
是完全确定的

理论上,您可能会受到Android版本上旧的修改过的BouncyCastle库版本中的bug()的影响。如果您将
SHA512withRSA
改为使用,那么这样的错误可能会被消除,至少引用的错误是

但是,在开始深入研究散列算法之前,请检查“接近主页”

也许您通过调用
String.getBytes
获得了字节数组。此调用取决于默认的平台编码,该编码介于Android 2.2和Android 2.3之间。这意味着,虽然两种情况下的字符串相同,但字节数组可能不同

要控制编码并使代码平台独立,请将编码指定为参数:

plainText.getBytes("UTF-8")
如果做不到这一点,还有一些策略可以实现独立于平台的实现

  • 等到2.2版本,可能有bug的库就会消失
  • 将已知良好库(jar)与软件一起分发。如果这是BouncyCastle,那么您将无法确保加载的是您的类而不是Android的类。解决方案称为海绵城堡
  • 使用对齐/填充。通过添加您自己的固定填充,尝试使以字节为单位的消息长度与0、55、56或63模64相等,并希望这些选项之一将开始提供可移植签名。选择这些值是为了与可疑算法的最外面部分交互,该部分填充到512位块

虽然粘贴错误处理程序几乎没有必要,但代码看起来是正确的。确保密钥和要签名的数据相同。@SevaAlekseyev是的,我确信我的系统的所有输入都相同。我将它们硬编码为静态final,在一个类中,包含这些常量。我并不是为了方便而链接常量值。一步一步地调试。首先,计算所有这些平台上的SHA256哈希,并比较它们。@SevaAlekseyev SHA256是相同的。但是如何调试
签名
java类呢?RSA加密和解密工作,但不是签名。谢谢你的回答Jirka。我将
SHA256withRSA
更改为
SHA512withRSA
,但它没有解决这个问题。对于3.2.1和3.2 android设备,我仍然有相同的签名,emulator(2.1)仍然有不同的签名。输入不是
字符串
,而是硬编码的
字节[]
。还有其他的想法吗?我也得到了与3.2.1和3.2相同的输出,一个仿真的4.0.3设备。@ FranckStudiesCommEng -答案扩展了三条路线,我会考虑下一步。谢谢Jirka,加载SpongyCastle使它工作在Android 2.2和3。x/4。x!