如何在Java中签名和验证RSA PKCS#1 v2.0签名
我正在尝试在RSA+SHA1中使用PKCS1 v2.0填充对签名进行签名和验证。 我在文档(JDK或JCE)中没有找到我必须使用的算法/填充。 似乎我不得不使用OAEP填充,但我没有成功: 为了验证,我尝试使用签名者发送的公钥在解密模式下使用密码:如何在Java中签名和验证RSA PKCS#1 v2.0签名,java,rsa,digital-signature,jce,Java,Rsa,Digital Signature,Jce,我正在尝试在RSA+SHA1中使用PKCS1 v2.0填充对签名进行签名和验证。 我在文档(JDK或JCE)中没有找到我必须使用的算法/填充。 似乎我不得不使用OAEP填充,但我没有成功: 为了验证,我尝试使用签名者发送的公钥在解密模式下使用密码: Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWITHSHA1ANDMGF1PADDING", "SunJCE"); cipher.init(Cipher.DECRYPT_MODE, pub); /
Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWITHSHA1ANDMGF1PADDING", "SunJCE");
cipher.init(Cipher.DECRYPT_MODE, pub); //exception !
但我有一个例外:
java.security.InvalidKeyException: OAEP cannot be used to sign or verify signatures
at com.sun.crypto.provider.RSACipher.init(RSACipher.java:303)
at com.sun.crypto.provider.RSACipher.engineInit(RSACipher.java:207)
...
(由于未知原因,OAEPWithHA1和MGF1padding仅在加密模式+公钥或解密模式+私钥的情况下被接受,与我想做的相反……)
对于签名,我尝试使用签名,但不知道使用哪种算法:
Signature mySig2 = Signature.getInstance("SHA1withRSAandMGF1");
不起作用:
java.security.NoSuchAlgorithmException: SHA1withRSAandMGF1 Signature not available
at java.security.Signature.getInstance(Signature.java:229)
...
有人能帮我吗
我正在尝试在RSA+SHA1中使用PKCS1 v2.0填充对签名进行签名和验证
这是一个奇怪的要求
首先,即使使用与PKCS#1 v1.5兼容的填充,RSA也是安全的。然而,当使用SHA-1散列输入/消息时,它是不安全的,原因很简单,出于这种目的,SHA-1不再被认为是安全的
第二,尽管PKCS#1 v2.0包含一种新的签名生成填充模式,称为PSS,或者更准确地说,称为RSASSA-PSS,但它也包含标准RSASSA-PKCS1-v1#5中1.5的单一签名生成模式。所以,至少在理论上,你的要求并不明确
现在PKCS#1v1.5paddingfor encryption已被认为可以抵御padding-oracle攻击。仅出于这个原因,PKCS#1 v2.0中引入的OAEP加密通常是可用的 用于签名生成的PSS具有更好的安全性证明,但PKCS#1 v1.5仍然被认为是安全的。这可能就是Oracle/SUN没有在JavaSEJCA中包含PSS的原因。如果你想要,你可以投赞成票
我在文档(JDK或JCE)中没有找到我必须使用的算法/填充。似乎我不得不使用OAEP填充,但我没有成功 OAEP代表最佳非对称加密填充。加密填充不能/不应用于签名生成
添加Bouncy Castle提供程序后,RSA PSS将可用。您可以将您的(不安全的)方案与
“SHA1 WithRSA/PSS”
一起使用,或者与相同的“SHA1 WithRSA和MGF1”
一起使用。一旦TLS1.3规范最终确定,Oracle的Java SE很可能会支持RSA/PSS
我正在尝试在RSA+SHA1中使用PKCS1 v2.0填充对签名进行签名和验证
这是一个奇怪的要求
首先,即使使用与PKCS#1 v1.5兼容的填充,RSA也是安全的。然而,当使用SHA-1散列输入/消息时,它是不安全的,原因很简单,出于这种目的,SHA-1不再被认为是安全的
第二,尽管PKCS#1 v2.0包含一种新的签名生成填充模式,称为PSS,或者更准确地说,称为RSASSA-PSS,但它也包含标准RSASSA-PKCS1-v1#5中1.5的单一签名生成模式。所以,至少在理论上,你的要求并不明确
现在PKCS#1v1.5paddingfor encryption已被认为可以抵御padding-oracle攻击。仅出于这个原因,PKCS#1 v2.0中引入的OAEP加密通常是可用的 用于签名生成的PSS具有更好的安全性证明,但PKCS#1 v1.5仍然被认为是安全的。这可能就是Oracle/SUN没有在JavaSEJCA中包含PSS的原因。如果你想要,你可以投赞成票
我在文档(JDK或JCE)中没有找到我必须使用的算法/填充。似乎我不得不使用OAEP填充,但我没有成功 OAEP代表最佳非对称加密填充。加密填充不能/不应用于签名生成
添加Bouncy Castle提供程序后,RSA PSS将可用。您可以将您的(不安全的)方案与
“SHA1 WithRSA/PSS”
一起使用,或者与相同的“SHA1 WithRSA和MGF1”
一起使用。一旦TLS 1.3规范最终确定,Oracle的Java SE很可能会支持RSA/PSS。希望我现在回应这个问题不会太晚。最近,我不得不面对RSA加密的同样问题。我的签名人想对通过POST发送的数据进行验证。这就是我如何在Java中处理这个问题的方法
步骤1-将以下内容添加到项目中
bcprov-ext-jdk14-1.45.jar
commons-codec-1.4.jar
步骤2-声明密码
private Cipher cipher;
步骤3-在类构造函数中调用下面的
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
this.cipher = Cipher.getInstance("RSA/NONE/OAEPWithSHA1AndMGF1Padding");
步骤4-从公钥文本字符串获取公钥
public PublicKey getPublic(String pubKey) throws Exception {
byte[] publicBytes = Base64.decodeBase64(pubKey);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
return keyFactory.generatePublic(keySpec);
}
第5步-验证方法
public boolean verfyRSA(String signature, String data, PublicKey key) throws Exception {
byte[] sign = Base64.decodeBase64(signature);
byte[] dat = Base64.decodeBase64(data);
Signature rsaVerify = Signature.getInstance("SHA1withRSAandMGF1");
rsaVerify.initVerify(key);
rsaVerify.update(dat);
return rsaVerify.verify(sign);
}
步骤6-使用
Yourclass yc = new YourClass();
PublicKey publicKey = yc.getPublic("Your PublicKey without leading and trailing -------text------");
boolean b = yc.verfyRSA("POST_Signature", "POST_data", publicKey);
希望这有帮助。注意getInstance()参数。这些就是成功的秘诀。干杯希望我还来得及回答这个问题。最近,我不得不面对RSA加密的同样问题。我的签名人想对通过POST发送的数据进行验证。这就是我如何在Java中处理这个问题的方法 步骤1-将以下内容添加到项目中
bcprov-ext-jdk14-1.45.jar
commons-codec-1.4.jar
步骤2-声明密码
private Cipher cipher;
步骤3-在类构造函数中调用下面的
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
this.cipher = Cipher.getInstance("RSA/NONE/OAEPWithSHA1AndMGF1Padding");
步骤4-从公钥文本字符串获取公钥
public PublicKey getPublic(String pubKey) throws Exception {
byte[] publicBytes = Base64.decodeBase64(pubKey);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
return keyFactory.generatePublic(keySpec);
}
第5步-验证方法
public boolean verfyRSA(String signature, String data, PublicKey key) throws Exception {
byte[] sign = Base64.decodeBase64(signature);
byte[] dat = Base64.decodeBase64(data);
Signature rsaVerify = Signature.getInstance("SHA1withRSAandMGF1");
rsaVerify.initVerify(key);
rsaVerify.update(dat);
return rsaVerify.verify(sign);
}
步骤6-使用
Yourclass yc = new YourClass();
PublicKey publicKey = yc.getPublic("Your PublicKey without leading and trailing -------text------");
boolean b = yc.verfyRSA("POST_Signature", "POST_data", publicKey);
希望这有帮助。注意getInstance()参数。这些就是成功的秘诀。干杯您在这里谈论的是RSA-PSS,它相当于签名的OAEP。可能重复的
签名。getInstance(“SHA1withRSAandMGF1”)
似乎可以从BouncyCastle获得。另外:好的,谢谢,我将寻找RSA-PSS。您在这里谈论的RSA-PSS相当于签名的OAEP。可能重复的签名。getInstance(“SHA1withRSAandMGF1”)
似乎可以从BouncyCastle获得。另外:好的,谢谢,我将寻找RSA-PSS。非常感谢您的精确性。PKCS 1 v2的要求。0由银行应用程序的编辑器提供。