【问题标题】:javax.crypto.BadPaddingException -Doing Decryption by AES256 with Salt and IVjavax.crypto.BadPaddingException - 使用 Salt 和 IV 通过 AES256 进行解密
【发布时间】:2018-07-09 14:09:51
【问题描述】:

我正在使用带有盐和 IV 的 AES 来加密和解密唯一 ID,但它在解密时给出 javax.crypto.BadPaddingException。

每次解密数据时都会给出完整的错误堆栈跟踪

javax.crypto.BadPaddingException: Given final block not properly padded null


at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:991)
    at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:847)
    at com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:446)
    at javax.crypto.Cipher.doFinal(Cipher.java:2165)
    at com.data.commons.security.impl.DataAESCrypt.decode(DataAESCrypt.java:84)
    at com.data.CryptoTest.main(CryptoTest.java:13)

加密方式 -

private static final int PASSWORD_ITERATIONS = 65536;
private static final int KEY_LENGTH          = 256;
private static byte[] salt = new byte[16];
private static byte[] iv= new byte[16];
private static final String ALGORITHM = "AES/CBC/PKCS5Padding" ;


@Override
public String encode(String plainText) throws Exception {
    // TODO Auto-generated method stub
       try {
            SecureRandom random = new SecureRandom();

            random.nextBytes(salt);

            SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
            KeySpec spec = new PBEKeySpec(plainText.toCharArray(), salt, PASSWORD_ITERATIONS, KEY_LENGTH);
            SecretKey tmp = factory.generateSecret(spec);
            SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");

            Cipher cipher = Cipher.getInstance(ALGORITHM);
            AlgorithmParameters params = cipher.getParameters();
             iv = params.getParameterSpec(IvParameterSpec.class).getIV();
             cipher.init(Cipher.ENCRYPT_MODE, secret);
            byte[] encryptedText = cipher.doFinal(plainText.getBytes("UTF-8"));


            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            outputStream.write(salt);
            outputStream.write(iv);
            outputStream.write(encryptedText);

            System.out.println("Salt " + DatatypeConverter.printBase64Binary(salt) + " IV " + DatatypeConverter.printBase64Binary(iv) );

            return DatatypeConverter.printBase64Binary(outputStream.toByteArray());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;

}

解密方法

public String decode(String encodedText) throws Exception {
    // TODO Auto-generated method stub
    try {
        byte[] ciphertext = DatatypeConverter.parseBase64Binary(encodedText);
        if (ciphertext.length < 48) {
            return null;
        }
        byte[] salt = Arrays.copyOfRange(ciphertext, 0, 16);
        byte[] iv = Arrays.copyOfRange(ciphertext, 16, 32);
        byte[] ct = Arrays.copyOfRange(ciphertext, 32, ciphertext.length);

        System.out.println("Salt " + DatatypeConverter.printBase64Binary(salt) + " IV " + DatatypeConverter.printBase64Binary(iv) );
        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
        KeySpec spec = new PBEKeySpec(encodedText.toCharArray(), salt, PASSWORD_ITERATIONS, KEY_LENGTH);
        SecretKey tmp = factory.generateSecret(spec);
        SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");
        Cipher cipher = Cipher.getInstance(ALGORITHM);

        cipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(iv));
        byte[] plaintext = cipher.doFinal(ct);

        return new String(plaintext, "UTF-8");
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;

}

我是 JCA 的新手。

【问题讨论】:

    标签: java encryption cryptography aes salt


    【解决方案1】:

    您在PBEKeySpec 中使用plainText.toCharArray()encodedText.toCharArray() 作为密码。相反,请使用实际的密码。目前只有知道明文消息才能取回明文消息,这并不是那么有用。用编码后的密文作为输入解密肯定行不通。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-07-07
      • 1970-01-01
      • 1970-01-01
      • 2016-04-06
      • 1970-01-01
      • 1970-01-01
      • 2016-01-16
      相关资源
      最近更新 更多