Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/361.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Java中签名和验证RSA PKCS#1 v2.0签名_Java_Rsa_Digital Signature_Jce - Fatal编程技术网

如何在Java中签名和验证RSA PKCS#1 v2.0签名

如何在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); /

我正在尝试在RSA+SHA1中使用PKCS1 v2.0填充对签名进行签名和验证。 我在文档(JDK或JCE)中没有找到我必须使用的算法/填充。 似乎我不得不使用OAEP填充,但我没有成功:

为了验证,我尝试使用签名者发送的公钥在解密模式下使用密码:

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由银行应用程序的编辑器提供。