AES密码 - javax.crypto.IllegalBlockSizeException使用填充密码解密时,输入长度必须是16的倍数

时间:2016-05-07 19:45:12

标签: java string encryption aes block-cipher

我创建了一个使用AES Cipher加密和解密字符串的类。

但是当我运行我的加密方法时,我得到一个javax.crypto.IllegalBlockSizeException错误

完整筹码:

javax.crypto.IllegalBlockSizeException: Input length must be multiple of 16 when decrypting with padded cipher
    at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:913)
    at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:824)
    at com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:436)
    at javax.crypto.Cipher.doFinal(Cipher.java:2165)
    at CipherEncrypter.decrypt(CipherEncrypter.java:46)
    at CipherEncrypter.decrypt(CipherEncrypter.java:42)

CipherEncrypter类:

import java.nio.charset.StandardCharsets;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.UUID;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

public class CipherEncrypter extends Encrypter<SecretKeySpec> {

    byte[] iv;
    private Cipher cipher;
    private IvParameterSpec ivSpec;



public CipherEncrypter() throws NoSuchAlgorithmException, NoSuchPaddingException {
        cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        generateKey();
    }

    public String encrypt(String input) throws InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {
        return new String(encrypt(input.getBytes(StandardCharsets.UTF_8)));
    }
    public byte[] encrypt(byte[] input) throws InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {
        byte[] iv = new byte[cipher.getBlockSize()];
        new SecureRandom().nextBytes(iv);
        ivSpec = new IvParameterSpec(iv);

        cipher.init(Cipher.ENCRYPT_MODE, key, ivSpec);
        byte[] encrypted = cipher.doFinal(input);

        return encrypted;
    }

    public String decrypt(String encrypted) throws InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {
        return new String(decrypt(encrypted.getBytes(StandardCharsets.UTF_8)), StandardCharsets.UTF_8);
    }
    public byte[] decrypt(byte[] encrypted) throws InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {
        cipher.init(Cipher.DECRYPT_MODE, key, ivSpec);
        byte[] decrypted = cipher.doFinal(encrypted);
        System.out.println("decrypted: " + new String(decrypted, StandardCharsets.UTF_8));

        return decrypted;
    }

    public SecretKeySpec generateKey() throws NoSuchAlgorithmException {
        return generateKey(UUID.randomUUID().toString());
    }
    public SecretKeySpec generateKey(String seed) throws NoSuchAlgorithmException {
        MessageDigest digest = MessageDigest.getInstance("SHA-256");
        digest.update(seed.getBytes());
        byte[] keyBytes = new byte[16];
        System.arraycopy(digest.digest(), 0, keyBytes, 0, keyBytes.length);
        key = new SecretKeySpec(keyBytes, "AES");
        return key;
    }

}

加密类:

import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;

import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;

public abstract class Encrypter<T> {

    public T key;


    public abstract String encrypt(String str) throws InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException;
    public abstract String decrypt(String str) throws InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException;

    public abstract T generateKey() throws Exception;

    public void setKey(T key) { this.key = key; }
    public T getKey() { return key; }

}

编辑:

29: return Base64.getEncoder().encodeToString(encrypt(input.getBytes(StandardCharsets.UTF_8)));

34: return new String(decrypt(Base64.getDecoder().decode(encrypted)), StandardCharsets.UTF_8);

现在又出现了另一个错误:

java.lang.IllegalArgumentException: Illegal base64 character d
IllegalArgumentException
    at java.util.Base64$Decoder.decode0(Unknown Source)
    at java.util.Base64$Decoder.decode(Unknown Source)
    at java.util.Base64$Decoder.decode(Unknown Source)
    at CipherEncrypter.decrypt(CipherEncrypter.java:43)

0 个答案:

没有答案