首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java AES提供BadPaddingException

Java AES提供BadPaddingException
EN

Stack Overflow用户
提问于 2020-07-03 17:07:00
回答 1查看 238关注 0票数 0

我正在尝试用Java为我的程序编写一个简单的加密和解密方法。它应该使用另一个字符串作为密钥对字符串进行加密和解密。

在测试过程中,出现BadPaddingException

我当前要加密的方法:

代码语言:javascript
复制
public String encrypt(String strToEncrypt, String secretKey) {
        try {
            SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
            byte[] salt = new Hash().hashString(secretKey).getBytes();
            KeySpec spec = new PBEKeySpec(secretKey.toCharArray(), salt, 65536, 256);
            SecretKey tmp = factory.generateSecret(spec);
            SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");

            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            byte[] iv = cipher.getParameters().getParameterSpec(IvParameterSpec.class).getIV();
            IvParameterSpec ivspec = new IvParameterSpec(iv);
            cipher.init(Cipher.ENCRYPT_MODE, secret, ivspec);

            byte[] ciphertext = cipher.doFinal(strToEncrypt.getBytes("UTF-8"));
            System.out.println("Finished encryption");
            return new Base64().encodeToString(ciphertext);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

我当前要解密的方法:

代码语言:javascript
复制
public String decrypt(String strToDecrypt, String secretKey) {  
        try {
            SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
            byte[] salt = new Hash().hashString(secretKey).getBytes();
            KeySpec spec = new PBEKeySpec(secretKey.toCharArray(), salt, 65536, 256);
            SecretKey tmp = factory.generateSecret(spec);
            SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");

            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            byte[] iv = cipher.getParameters().getParameterSpec(IvParameterSpec.class).getIV();
            IvParameterSpec ivspec = new IvParameterSpec(iv);
            cipher.init(Cipher.DECRYPT_MODE, secret, ivspec);
            
            byte[] decodedPlaintext = new Base64().decode(strToDecrypt);
            byte[] plaintext = cipher.doFinal(decodedPlaintext);
            System.out.println("Finished decryption");
            return new Base64().encodeToString(plaintext);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

我得到了以下异常:

代码语言:javascript
复制
javax.crypto.BadPaddingException: Given final block not properly padded. Such issues can arise if a bad key is used during decryption.
    at java.base/com.sun.crypto.provider.CipherCore.unpad(CipherCore.java:975)
    at java.base/com.sun.crypto.provider.CipherCore.fillOutputBuffer(CipherCore.java:1056)
    at java.base/com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:853)
    at java.base/com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:446)
    at java.base/javax.crypto.Cipher.doFinal(Cipher.java:2202)
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-07-04 03:52:23

在迈克尔和詹姆斯·K·波尔克总统的热情帮助下,我可以使加密和解密工作,并改进盐的生成。我的错误是,我没有使用相同的IvParameterSpec进行加密和解密。

我的加密方法:

代码语言:javascript
复制
public static String encrypt(String strToEncrypt, String secretKey) {
        try {
            SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
            byte[] salt = new byte[16];
            SecureRandom.getInstanceStrong().nextBytes(salt);
            KeySpec spec = new PBEKeySpec(secretKey.toCharArray(), salt, 65536, 256);
            SecretKey tmp = factory.generateSecret(spec);
            SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");

            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            byte[] iv = cipher.getParameters().getParameterSpec(IvParameterSpec.class).getIV();
            IvParameterSpec ivspec = new IvParameterSpec(iv);
            cipher.init(Cipher.ENCRYPT_MODE, secret, ivspec);

            byte[] ivBytes = ivspec.getIV();
            byte[] ciphertext = cipher.doFinal(strToEncrypt.getBytes("UTF-8"));
            System.out.println("Finished encryption");
            byte[] outputBytes = concat(concat(salt, ivBytes), ciphertext);
            return new Base64().encodeToString(outputBytes);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

我的解密方法:

代码语言:javascript
复制
public static String decrypt(String strToDecrypt, String secretKey) {
        try {
            byte[] decodedCiphertext = new Base64().decode(strToDecrypt);
            SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
            byte[] salt = Arrays.copyOfRange(decodedCiphertext, 0, 16);
            KeySpec spec = new PBEKeySpec(secretKey.toCharArray(), salt, 65536, 256);
            SecretKey tmp = factory.generateSecret(spec);
            SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");

            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            byte[] iv = Arrays.copyOfRange(decodedCiphertext, 16, 32);
            IvParameterSpec ivspec = new IvParameterSpec(iv);
            cipher.init(Cipher.DECRYPT_MODE, secret, ivspec);

            
            byte[] plaintext = cipher.doFinal(Arrays.copyOfRange(decodedCiphertext, 32, decodedCiphertext.length));
            System.out.println("Finished decryption");
            return new String(plaintext, "UTF-8");
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62712114

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档