我正在尝试使用方法initSign(PrivateKey privateKey, SecureRandom random)
计算文档的签名。
在调用该方法之前,我先声明了一个对象:
SecureRandom random = new SecureRandom();
但是,当我使用相同的密钥多次调用该方法时,即使随机数随时间变化,它也始终为我提供相同的签名,而不是将其随机化。
为什么?
最佳答案
您可能正在使用PKCS#1 v1.5填充方案之一。它们是使用MD2withRSA,MD5withRSA,SHA1withRSA,SHA256withRSA,SHA384withRSA,SHA512withRSA中的一种创建的。但是,这些方案都没有采用随机数作为参数。 RSA / PSS可以,但是它不包含在标准API中(不过您可以使用Bouncy Castle提供程序)。 ECDSA还使用随机数来生成签名。
Java密码体系结构定义了诸如Signature
类之类的通用类。这意味着将存在不适用于某些算法的方法和参数。在您的情况下,RSA PKCS v1.5签名生成只是忽略了随机数,因为它不需要它。
Security.addProvider(new BouncyCastleProvider());
for (int i = 0; i < 2; i++) {
Signature pss = Signature.getInstance("SHA256withRSA/PSS");
SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
// not random: random.setSeed(new byte[16]);
pss.initSign(generatedKeyPair.getPrivate(), random);
pss.update("owlstead".getBytes(StandardCharsets.UTF_8));
byte[] sig = pss.sign();
System.out.println(Hex.toHexString(sig));
}