我正在使用Bouncy Castle Library,如果不先对其进行散列/填充,就无法找到对原始消息进行签名的方法。我不确定要作为alg传递什么参数。
在使用PKCSv1.5填充对摘要进行签名时,我使用了:"SHA1WithRSA“、"SHA256WithRSA”等(根据摘要类型)。
signature = Signature.getInstance(alg, JCEProvider.CRYPTO_PROVIDER_NAME);发布于 2016-10-30 21:13:10
原始签名只不过是模幂运算。现在似乎有两个选择,但基本上只有一个会留下来。我将在下面解释。
首先,您可能认为在"NoneWithRSA"中使用Signature应该是可行的。该算法确实存在,但不幸的是,它仍然填充;它只是剥离了表示散列函数和值的ASN.1结构。所以其中一个是不可用的。
虽然是signing is not the same as encryption,但这两种运算最终都依赖于模幂运算。因此,幸运的是,可以使用Cipher实例创建所需的功能:
Security.addProvider(new BouncyCastleProvider());
Cipher rsa = Cipher.getInstance("RSA/ECB/NoPadding", BouncyCastleProvider.PROVIDER_NAME);
rsa.init(Cipher.DECRYPT_MODE, kp.getPrivate());
byte[] signatureUsingCipher = rsa.doFinal("owlstead"
.getBytes(StandardCharsets.UTF_8));
System.out.println(Hex.toHexString(signatureUsingCipher));这里需要注意的一件事是,Bouncy Castle执行的操作与Oracle的SunJCE提供程序略有不同。它不仅删除了填充,还忘记将密文通过I2OSP算法(请参阅PKCS#1标准),该算法将正确地编码为模数的输出大小。因此,对于特定的密钥/明文组合,您可以使用小于128字节的密文。通过加密值0可以很容易地看到这一点,其中输出将是零字节。
最后,请注意,指定Cipher.ENCRYPT模式或Cipher.DECRYPT模式没有区别;两者都只是执行模幂运算。但是,Cipher.DECRYPT更可能需要一个私钥,这就是我在上面的代码中使用它的原因。
您可以生成密钥对来测试上面的代码,如下所示:
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(1024);
KeyPair kp = kpg.generateKeyPair();警告:没有安全填充的签名生成是不安全的;it may result in existential forgery attacks。您只能将其用作创建安全方案的构建块。
发布于 2017-07-18 17:28:39
Signature signature = Signature.getInstance("NONEwithRSA","BC");参见http://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#Signature。
https://stackoverflow.com/questions/40242391
复制相似问题