javax.crypto.BadPaddingException: Decryption error : while doing only Decrypt to an already encypted string from DB

huangapple go评论78阅读模式
英文:

javax.crypto.BadPaddingException: Decryption error : while doing only Decrypt to an already encypted string from DB

问题

这个错误已经在几个链接中讨论过。

我遇到了类似的错误,但我的情况与其他人有些不同。
我需要:

> 仅需要 解密,不需要加密。

在我的情况下,一个加密的消息已经存储在数据库中。我将其作为字符串获取,现在只需要对其进行解密以获取原始字符串。

任何建议都将非常有帮助。

我的代码片段如下:

String encodedStr = "c2J7RiP1CY++gfdE7Ke/xD1fSOOdO7DvprdZZUDws9Yl8DmYJV64zGV9vvK/TMEfALqSPH8KcZik8XvmLowpjJWzYY2Of1aytHaya0ULwmopklRWlkaS5sjL80jjyhaRN2O+zQNarbAQy8g3VtXX643T2AhDTsT+NKFsCcpH4xbqmViwD1GXQQLsLwuKZx1POAtyC0UaMjQ2SrzR+eVEiSgKPDABDKIRbOyBEXRcJMK/t/P7uIk9tJ/p1X2JqQOO7GMO/1x7rvF6Pb1Fik2tmQv5qL1W6/kV97/VT5Hpi9uh6zdCFO7sstYvgkxxbs3gTyJ5raWlATVU6a/0B/Q50w==";
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
keyGen.initialize(2048);
KeyPair pair = keyGen.generateKeyPair();
PrivateKey privateKey = pair.getPrivate();
PublicKey publicKey = pair.getPublic();

Cipher cipher = Cipher.getInstance("RSA");
// 不需要加密。
//cipher.init(Cipher.ENCRYPT_MODE, privateKey);
//String ss = Base64.encodeBase64String(cipher.doFinal(encodedStr.getBytes("UTF-8")));
//System.out.println(ss);

// 仅需要解密。
cipher.init(Cipher.DECRYPT_MODE, publicKey);
String sss = new String(cipher.doFinal(Base64.decodeBase64(encodedStr)), "UTF-8");
System.out.println(sss);

但在每次运行到cipher.doFinal(Base64.decodeBase64(encodedStr)这一行时,我得到以下异常:

Exception in thread "main" javax.crypto.BadPaddingException: Decryption error
    at sun.security.rsa.RSAPadding.unpadV15(RSAPadding.java:383)
    at sun.security.rsa.RSAPadding.unpad(RSAPadding.java:294)
    at com.sun.crypto.provider.RSACipher.doFinal(RSACipher.java:356)
    at com.sun.crypto.provider.RSACipher.engineDoFinal(RSACipher.java:389)
    at javax.crypto.Cipher.doFinal(Cipher.java:2164)
    at com.sprint.neo.bc4j.util.TestMain.main(TestMain.java:20)

尽管我不需要加密,Cipher.ENCRYPT_MODE工作正常。
但是对于Cipher.DECRYPT_MODE,它会抛出异常。
请指导我,如何仅对已存在于数据库中的加密字符串进行解密,以获取原始字符串值。

英文:

This error is already discussed in several links.

I got the similar kind of errors, But my scenario is little different than others.
I need

> only Decryption. not Encryption.

In my case, an encrypted message is already stored in the DB. I got that as String and now need to only decrypt it to get the original String.

Any suggestions will be very helpful.

My piece of code is as follows:

String encodedStr = "c2J7RiP1CY++gfdE7Ke/xD1fSOOdO7DvprdZZUDws9Yl8DmYJV64zGV9vvK/TMEfALqSPH8KcZik8XvmLowpjJWzYY2Of1aytHaya0ULwmopklRWlkaS5sjL80jjyhaRN2O+zQNarbAQy8g3VtXX643T2AhDTsT+NKFsCcpH4xbqmViwD1GXQQLsLwuKZx1POAtyC0UaMjQ2SrzR+eVEiSgKPDABDKIRbOyBEXRcJMK/t/P7uIk9tJ/p1X2JqQOO7GMO/1x7rvF6Pb1Fik2tmQv5qL1W6/kV97/VT5Hpi9uh6zdCFO7sstYvgkxxbs3gTyJ5raWlATVU6a/0B/Q50w==";
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
keyGen.initialize(2048);
KeyPair pair = keyGen.generateKeyPair();
PrivateKey privateKey = pair.getPrivate();
PublicKey publicKey = pair.getPublic();

Cipher cipher = Cipher.getInstance("RSA");
// Encryption is not required.
//cipher.init(Cipher.ENCRYPT_MODE, privateKey);
//String ss =Base64.encodeBase64String(cipher.doFinal(encodedStr.getBytes("UTF-8")));
//System.out.println(ss);

// Only decryption is required.
cipher.init(Cipher.DECRYPT_MODE, publicKey);
String sss = new String(cipher.doFinal(Base64.decodeBase64(encodedStr)), "UTF-8");
System.out.println(sss);

And I'm getting below exception everytime at the line cipher.doFinal(Base64.decodeBase64(encodedStr) :

Exception in thread "main" javax.crypto.BadPaddingException: Decryption error
	at sun.security.rsa.RSAPadding.unpadV15(RSAPadding.java:383)
	at sun.security.rsa.RSAPadding.unpad(RSAPadding.java:294)
	at com.sun.crypto.provider.RSACipher.doFinal(RSACipher.java:356)
	at com.sun.crypto.provider.RSACipher.engineDoFinal(RSACipher.java:389)
	at javax.crypto.Cipher.doFinal(Cipher.java:2164)
	at com.sprint.neo.bc4j.util.TestMain.main(TestMain.java:20)

Though I don't require encryption, the Cipher.ENCRYPT_MODE is working fine.
But incase of Cipher.DECRYPT_MODE , it's throwing exception.
Please suggest me, how can I only decrypt an already existing encrypted String from DB, to get the original String value.

答案1

得分: 0

以下是可以工作的代码片段:

public static void main(String[] args) {

    byte[] txt = "message".getBytes();
    byte[] encText;
    try{

        // 加载密钥库
        KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
        char[] password = "keystorePassword".toCharArray();

        Key rsakey = ks.getKey("mykeyalias", password);
        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");

        // 加密
        Certificate cert = ks.getCertificate("mykeyalias");
        try
        {
            cipher.init(Cipher.ENCRYPT_MODE, cert.getPublicKey());
            encText = cipher.doFinal(txt);
            System.out.println(encText.toString());
        }
        catch (Throwable e)
        {
            e.printStackTrace();
            return;
        }

        // 解密
        cipher.init(Cipher.DECRYPT_MODE, rsakey);
        String decrypted = new String(cipher.doFinal(encText));
        System.out.println(decrypted);


    } catch (Exception e) {
        System.out.println("error" + e);
    }
}
英文:

Here is the piece of code which works:

public static void main(String[] args) {

    byte[] txt = "message".getBytes();
    byte[] encText;
    try{

        // Load the keystore
        KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
        char[] password = "keystorePassword".toCharArray();

        Key rsakey = ks.getKey("mykeyalias", password);
        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");

        // Encrypt
        Certificate cert = ks.getCertificate("mykeyalias");
        try
        {
            cipher.init(Cipher.ENCRYPT_MODE, cert.getPublicKey());
            encText = cipher.doFinal(txt);
            System.out.println(encText.toString());
        }
        catch (Throwable e)
        {
            e.printStackTrace();
            return;
        }

        // Decrypt
        cipher.init(Cipher.DECRYPT_MODE, rsakey);
        String decrypted = new String(cipher.doFinal(encText));
        System.out.println(decrypted);


    } catch (Exception e) {
        System.out.println("error" + e);
    }

}

答案2

得分: 0

你生成的公钥每次都会不同,因此加密后的字符串也会不同。生成的字符串将不再有效用于解密。
尝试从文件中读取密钥秘密,并使用相同的加密字符串进行解密。

英文:

Your publicKey generated will be different each time and hence the encrypted String will be different. The string generated will no longer be valid for decryption.
Try to read key secret from a file and use same encrypted string to decrypt.

huangapple
  • 本文由 发表于 2020年9月7日 14:41:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/63772520.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定