我正在尝试使用方法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));
}

10-06 04:57