“javax.crypto.BadPaddingException:数据必须从零开始”例外

发布于 2024-11-17 15:05:19 字数 2592 浏览 0 评论 0原文

我在解密字符串时遇到了上述异常。

下面是我的代码:

import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import javax.crypto.Cipher;

public class EncryptAndDecrypt {

    public static Cipher createCipher () throws Exception{

            Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");

            return cipher;
    }
    public static KeyPair generateKey () throws  NoSuchAlgorithmException{

            KeyPairGenerator keyGen = KeyPairGenerator.getInstance ("RSA");
            keyGen.initialize(1024);
            KeyPair key = keyGen.generateKeyPair();

            return key;
    }
    public static byte [] encrypt (String  str, Cipher cip, KeyPair key) {

        byte [] cipherText = null;
        try {

            byte [] plainText = str.getBytes("UTF8");
            cip.init(Cipher.ENCRYPT_MODE, key.getPublic());
            cipherText = cip.doFinal(plainText);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return cipherText;
    }
    public static String decrypt (byte [] c, Cipher cip, KeyPair key) throws Exception {

        cip.init(Cipher.DECRYPT_MODE, key.getPrivate());

        byte [] decryptedPlainText = cip.doFinal (c);// exception occurred here
        String decryptedPlainStr = new String (decryptedPlainText);

        return decryptedPlainStr;
    }
}


//separate class below to use the encrypt method

public class EncryptionApp {

    public static void main (String [] args) {

        getEncrypted();
    }
    public static byte [] getEncrypted () {

        byte [] encyptedByte = null;
        try {
            String plainText = "der";
            Cipher cip = Safety.createCipher();
            KeyPair key = Safety.generateKey();
            encyptedByte = Safety.useRSA(plainText, cip, key);
        }
        catch (Exception e) {
            e.printStackTrace();
        }

         return encyptedByte;
    }
}

// Another class to use the decrypt method 

public class DecryptionApp {

    public static void main(String[] args) {
        System.out.println (useDecrypted () );
    }
    public static byte[] useDecrypted () {

        byte [] decryptedText = null;
        try {
            Cipher cip = EncryptAndDecrypt.createCipher();
            KeyPair key = EncryptAndDecrypt.generateKey();
            decryptedText = EncryptAndDecrypt.decrypt(EncryptionApp.getEncrypted(),cip,key);
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    return decryptedText;
    }
}

I encountered the abovementioned exception while I was decrypting a string.

Below is my code:

import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import javax.crypto.Cipher;

public class EncryptAndDecrypt {

    public static Cipher createCipher () throws Exception{

            Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");

            return cipher;
    }
    public static KeyPair generateKey () throws  NoSuchAlgorithmException{

            KeyPairGenerator keyGen = KeyPairGenerator.getInstance ("RSA");
            keyGen.initialize(1024);
            KeyPair key = keyGen.generateKeyPair();

            return key;
    }
    public static byte [] encrypt (String  str, Cipher cip, KeyPair key) {

        byte [] cipherText = null;
        try {

            byte [] plainText = str.getBytes("UTF8");
            cip.init(Cipher.ENCRYPT_MODE, key.getPublic());
            cipherText = cip.doFinal(plainText);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return cipherText;
    }
    public static String decrypt (byte [] c, Cipher cip, KeyPair key) throws Exception {

        cip.init(Cipher.DECRYPT_MODE, key.getPrivate());

        byte [] decryptedPlainText = cip.doFinal (c);// exception occurred here
        String decryptedPlainStr = new String (decryptedPlainText);

        return decryptedPlainStr;
    }
}


//separate class below to use the encrypt method

public class EncryptionApp {

    public static void main (String [] args) {

        getEncrypted();
    }
    public static byte [] getEncrypted () {

        byte [] encyptedByte = null;
        try {
            String plainText = "der";
            Cipher cip = Safety.createCipher();
            KeyPair key = Safety.generateKey();
            encyptedByte = Safety.useRSA(plainText, cip, key);
        }
        catch (Exception e) {
            e.printStackTrace();
        }

         return encyptedByte;
    }
}

// Another class to use the decrypt method 

public class DecryptionApp {

    public static void main(String[] args) {
        System.out.println (useDecrypted () );
    }
    public static byte[] useDecrypted () {

        byte [] decryptedText = null;
        try {
            Cipher cip = EncryptAndDecrypt.createCipher();
            KeyPair key = EncryptAndDecrypt.generateKey();
            decryptedText = EncryptAndDecrypt.decrypt(EncryptionApp.getEncrypted(),cip,key);
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    return decryptedText;
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

倾听心声的旋律 2024-11-24 15:05:19

您已经在 "javax.crypto.BadPaddingException 中提出了同样的问题:数据必须从零开始”例外,我给了你一个答案:你使用两个不同的密钥对:一个用于加密,另一个用于解密。那是行不通的。我什至给了您一个代码示例,表明如果您使用相同的密钥对,一切都会正常运行。

KeyPairGenerator.generateKeyPair() 生成密钥对。调用此方法两次将获得两个不同的密钥对:它在内部使用随机数生成器来生成始终不同的密钥对。

您必须生成一次密钥对,将其存储在变量中,并使用该变量进行加密和解密。

您应该阅读您正在使用的类和方法的文档。 generateKeyPair 文档 说:

这将生成一个新的密钥对
每次被调用时。

You already asked the same question in "javax.crypto.BadPaddingException: Data must start with zero" exception, and I gave you an answer: you're using two different keypairs : one to encrypt, and another one to decrypt. That can't work. I even gave you a code sample showing that everything ran fine if you used the same keypair.

KeyPairGenerator.generateKeyPair() generates a keypair. Calling this method twice will get you two different keypairs: it uses a random number generator internally to generate always different keypairs.

You must generate a keypair once, store it in a variable, and use this variable to encrypt and decrypt.

You should read the documentation of the classes and methods you are using. The documentation of generateKeyPair says:

This will generate a new key pair
every time it is called.

千笙结 2024-11-24 15:05:19

将此 main 方法添加到 EncryptAndDecrypt 中,并执行它。你会发现一切都运转良好。

public static void main(String[] args) throws Exception {
    String s = "hello";
    Cipher cipher = createCipher();
    KeyPair keyPair = generateKey();
    byte[] b = encrypt(s, cipher, keyPair);
    String s2 = decrypt(b, cipher, keyPair);
    System.out.println(s2);
}

问题在于您使用此类的方式。
useDecrypted 方法执行以下操作:

Cipher cip = EncryptAndDecrypt.createCipher(); // create a Cipher object using EncryptAndDecrypt
KeyPair key = EncryptAndDecrypt.generateKey(); // generate a KeyPair using EncryptAndDecrypt

// call EncryptionApp.getEncrypted() to get an encrypted text, then decrypt this encrypted text
// using the keypair created above.
decryptedVote = EncryptAndDecrypt.decrypt(EncryptionApp.getEncrypted(), cip, key);

getEncrypted 方法执行以下操作:

String plainText = "der"; // create some plain text
// create a Cipher instance. Is it the same algorithm as the one in useDecrypted?
// we don't know, because it uses another, unknown, Safety class
Cipher cip = Safety.createCipher(); 
// create a new KeyPair instance. Is it the same KeyPair as the one in useDecrypted?
// No : another keypair is generated. There is no way something encrypted using a keypair
// will decrypt correctly with another keypair.
KeyPair key = Safety.generateKey();
encyptedByte = Safety.useRSA(plainText, cip, key);

因此,简而言之,您使用两个不同的密钥对:一个用于加密,另一个用于解密。那是行不通的。

另请注意,在加密中,您使用UTF8编码将字符串转换为字节数组,而在解密中,您使用默认平台将字节数组转换为字符串编码。您应该对两者都使用 UTF8,因此在解密中使用以下代码:

String decryptedPlainStr = new String (decryptedPlainText, "UTF8");

Add this main method to EncryptAndDecrypt, and execute it. You'll see that evrything works fine.

public static void main(String[] args) throws Exception {
    String s = "hello";
    Cipher cipher = createCipher();
    KeyPair keyPair = generateKey();
    byte[] b = encrypt(s, cipher, keyPair);
    String s2 = decrypt(b, cipher, keyPair);
    System.out.println(s2);
}

The problem lies in the way you're using this class.
The useDecrypted method does the following:

Cipher cip = EncryptAndDecrypt.createCipher(); // create a Cipher object using EncryptAndDecrypt
KeyPair key = EncryptAndDecrypt.generateKey(); // generate a KeyPair using EncryptAndDecrypt

// call EncryptionApp.getEncrypted() to get an encrypted text, then decrypt this encrypted text
// using the keypair created above.
decryptedVote = EncryptAndDecrypt.decrypt(EncryptionApp.getEncrypted(), cip, key);

And the getEncrypted method does the following:

String plainText = "der"; // create some plain text
// create a Cipher instance. Is it the same algorithm as the one in useDecrypted?
// we don't know, because it uses another, unknown, Safety class
Cipher cip = Safety.createCipher(); 
// create a new KeyPair instance. Is it the same KeyPair as the one in useDecrypted?
// No : another keypair is generated. There is no way something encrypted using a keypair
// will decrypt correctly with another keypair.
KeyPair key = Safety.generateKey();
encyptedByte = Safety.useRSA(plainText, cip, key);

So, in short, you use two different keypairs : one to encrypt and the other to decrypt. That can't work.

Also, note that in encrypt, you transform your string into a byte array using the UTF8 encoding, whereas in decrypt, you transform the byte array into a String using the default platform encoding. You should use UTF8 for both, and thus use the following code in decrypt :

String decryptedPlainStr = new String (decryptedPlainText, "UTF8");
尾戒 2024-11-24 15:05:19

你用谷歌搜索过吗?当加密密钥与解密密钥不同时,很多人都会遇到这个问题。看起来您总是生成新密钥,而不是使用用于加密的相同密钥来解密。

Have you googled? A lot of people have this problem when the key to encrypt is not the same as the key to decrypt. It seems like you generate new keys all the time instead of using the same key to decrypt that you used for encryption.

与风相奔跑 2024-11-24 15:05:19

我收到此错误,在我的情况下,结果是我作为参数发送的 Base 64 字符串包含一些由于位于 URL 中而被更改的字符。解决方案是对参数进行 URL 编码。

I was getting this error and it turned out in my case to be that the base 64 string I was sending as a parameter contained some characters that were being altered because of being in a URL. The solution turned out to be URL encoding the parameter.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文