在Java中,如何基于数据进行签名,但如何基于哈希进行验证?
如何根据数据计算RSA签名,但根据数据的散列验证该签名(和/或反之亦然)?在内部对数据进行签名/验证只是对该数据进行散列,然后在散列上进行操作,在其他平台上我可以完成这一点。但在Java中,我想我似乎无法正确配置签名算法 如何仅使用数据的散列来验证签名 以下是我所拥有的:在Java中,如何基于数据进行签名,但如何基于哈希进行验证?,java,hash,cryptography,Java,Hash,Cryptography,如何根据数据计算RSA签名,但根据数据的散列验证该签名(和/或反之亦然)?在内部对数据进行签名/验证只是对该数据进行散列,然后在散列上进行操作,在其他平台上我可以完成这一点。但在Java中,我想我似乎无法正确配置签名算法 如何仅使用数据的散列来验证签名 以下是我所拥有的: import java.security.*; public class Main { public static void main(String[] args) throws Exception {
import java.security.*;
public class Main {
public static void main(String[] args) throws Exception
{
byte[] data = new byte[] {1,2,3};
MessageDigest digest = MessageDigest.getInstance("SHA1");
digest.update(data);
byte[] sha1Hash = digest.digest();
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(512);
KeyPair keyPair = kpg.genKeyPair();
Signature signingInstance = Signature.getInstance("SHA1withRSA");
signingInstance.initSign(keyPair.getPrivate());
signingInstance.update(data);
byte[] signature = signingInstance.sign();
Signature dataVerifyingInstance = Signature.getInstance("SHA1withRSA");
dataVerifyingInstance.initVerify(keyPair.getPublic());
dataVerifyingInstance.update(data);
boolean dataVerified = dataVerifyingInstance.verify(signature);
Signature hashVerifyingInstance = Signature.getInstance("NONEwithRSA");
hashVerifyingInstance.initVerify(keyPair.getPublic());
hashVerifyingInstance.update(sha1Hash);
boolean hashVerified = hashVerifyingInstance.verify(signature);
System.out.println("Verification based on data: " + dataVerified);
System.out.println("Verification based on hash: " + hashVerified);
}
}
运行此程序的输出为:
Verification based on data: true
Verification based on hash: false
您必须首先实现围绕哈希值构建的PKCS#1 v1.5填充(正式命名)。只有在这之后,
“NONEwithRSA”
的技巧才能发挥作用
当然,你可以作弊并查看BouncyCastle的源代码或Java的GPL版本。或者,您可以使用BouncyCastle轻量级API,但您将失去与JCA的兼容性,并添加一个依赖项
JavaCard
确实具有创建散列卡的功能。在功能齐全的PC机上运行的库中不需要这种功能(我在Java 7类中也找不到这种功能)。为什么不签名哈希呢?我可以。但是,当一方签名,另一方验证时,各方应该能够独立选择如何签名或验证数据。为什么?各方应就数据的签名、验证、散列、加密、格式化、存储和其他任何方式达成一致。关键是,数据应该独立于协议。各方没有理由必须同意是对散列本身进行签名,还是对数据进行散列签名,因为这是同一件事。我的代码应该有用。在其他平台上也是如此。历史:在当时,v1.5(用于签名或用于加密的不同版本)是行业标准PKCS#1文档中使用的唯一填充模式。因此,用于签名生成的RSA被简单地称为“[HASH]withRSA”,而实际上它是“[HASH]withPKCSV1_5andRSA”。新的/更好的PSS方案通过添加配置选项使这一点复杂化。这可以解释当我用公钥“加密”签名时,我在结果的索引16处发现了哈希值。这与您链接到的文档一致。谢谢