【问题标题】:javax.crypto.BadPaddingException: Decryption error : while doing only Decrypt to an already encypted string from DBjavax.crypto.BadPaddingException:解密错误:仅从数据库解密到已加密的字符串
【发布时间】:2020-09-07 06:41:21
【问题描述】:

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

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

解密。不是加密。

在我的例子中,一条加密消息已经存储在数据库中。我得到的是字符串,现在只需要解密它就可以得到原始字符串。

任何建议都会很有帮助。

我的一段代码如下:

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);

而且我每次在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 的情况下,它会抛出异常。 请建议我,我怎样才能只从数据库中解密一个已经存在的加密字符串,以获得原始字符串值。

【问题讨论】:

  • 由于您已经有一个“encodedString”,因此您无法生成新的密钥对并尝试使用新生成的密钥解密您的字符串。非对称加密使用密钥对的 PUBLIC 密钥完成,解密将使用同一密钥对的 PRIVATE 密钥。
  • 因此我怎样才能在这里解决这个问题,我已经有一个加密的字符串。
  • 作为加密的一部分,您之前已经生成了一个密钥对。使用公钥进行加密并保存两个密钥(私钥和公钥),例如在 Java 密钥库中。稍后 - 解密时 - 加载私钥 [见下面@Seema 的答案] 例如从密钥库中提取并将其用于解密。
  • 好吧,我试试把keyPair存起来,用私钥解密。
  • 我试过但无法在 java 密钥库中存储私钥和公​​钥。你能帮我一个代码sn-p吗?在@Seema 的回答中,我得到了 NullPointer,因为 Certificate cert 为空。

标签: java cryptography rsa


【解决方案1】:

这是一段有效的代码:

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);
    }

}

【讨论】:

  • 它不能解决我的问题。在这里,您加密了 message 文本,然后对其进行解密以获得相同的文本/字符串。但在我的场景中,我已经在数据库中保存了一个加密字符串,我需要对其进行解密以获得原始字符串。
  • 你能帮忙用一个代码 sn-p 将密钥对公私存储在Java keyStore
  • 你可以看看这个讨论:stackoverflow.com/questions/9890313/…
  • 谢谢。它在更大程度上有所帮助。
【解决方案2】:

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

【讨论】:

  • 好吧,我试试把keyPair存起来,以后用私钥解密。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多