简体   繁体   中英

javax.crypto.BadPaddingException error during AES encryption

I need to encrypt and decrypt a text using AES. I can call both method locally and it works, however when I run it outside the class I get javax.crypto.BadPaddingException error. I think I am losing data somewhere but U cannot find where. Here is the code:

public class AES {


    public String encryptAES(String seed, String cleartext) throws Exception {
        byte[] rawKey = getRawKey(seed.getBytes());
        byte[] result = encrypt(rawKey, cleartext.getBytes());
        return toHex(result);
    }

    public String decryptAES(String seed, String encrypted) throws Exception {
        byte[] rawKey = getRawKey(seed.getBytes());
        byte[] enc = toByte(encrypted);
        byte[] result = decrypt(rawKey, enc);
        return new String(result);
    }

    private byte[] getRawKey(byte[] seed) throws Exception {
        KeyGenerator kgen = KeyGenerator.getInstance("AES");
        SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
        sr.setSeed(seed);
        kgen.init(128, sr);

        SecretKey skey = kgen.generateKey();
        byte[] raw = skey.getEncoded();
        return raw;
    }


    private byte[] encrypt(byte[] raw, byte[] clear) throws Exception {
        SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
        byte[] encrypted = cipher.doFinal(clear);
        return encrypted;
    }

    private byte[] decrypt(byte[] raw, byte[] encrypted) throws Exception {
        SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.DECRYPT_MODE, skeySpec);
        byte[] decrypted = cipher.doFinal(encrypted);
        return decrypted;
    }

    private byte[] toByte(String hexString) {
        int len = hexString.length() / 2;
        byte[] result = new byte[len];
        for (int i = 0; i < len; i++)
            result[i] = Integer.valueOf(hexString.substring(2 * i, 2 * i + 2), 16).byteValue();
        return result;
    }

    private String toHex(byte[] buf) {
        if (buf == null)
            return "";
        StringBuffer result = new StringBuffer(2 * buf.length);
        String HEX = "0123456789ABCDEF";
        for (int i = 0; i < buf.length; i++) {


            result.append(HEX.charAt((buf[i] >> 4) & 0x0f)).append(HEX.charAt(buf[i] & 0x0f));
        }
        return result.toString();
    }

the error points to

byte[] decrypted = cipher.doFinal(encrypted);

I see several things that need fixing ..

Firstly the seed to SecureRandom won't make it produce the same output. So if you try to create the same key by specifying the same seed, it wont work.

Secondly .. you should make sure to instantiate your encrypt and decrypt cipher with the same properties .. currently you don't.

Also , when you specify CBC mode you need to handle the initialization vector . If you don't specify one on the encrypt, the cipher makes one for you .. this you need to grab and provide when you decrypt.

Fixing these things don't necessarily fix everything, but should lead you in the right direction. Take a look at some of the related question at the right side .. StackOverflow have numerous working AES examples.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM