AES 加密期间出现 javax.crypto.BadPaddingException 错误

标签 java encryption aes

我需要使用 AES 加密和解密文本。我可以在本地调用这两个方法并且它可以工作,但是当我在类之外运行它时,我收到 javax.crypto.BadPaddingException 错误。我认为我在某个地方丢失了数据,但你找不到哪里。 这是代码:

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();
    }

错误指向

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

最佳答案

我发现有几件事需要修复..

首先SecureRandom 的种子不会使其产生相同的输出。因此,如果您尝试通过指定相同的种子来创建相同的 key ,它将无法工作。

其次..您应该确保使用相同的属性实例化您的加密和解密密码..目前您没有。

此外,当您指定CBC模式时,您需要处理初始化 vector 。如果您没有在加密时指定一个,密码会为您生成一个。您需要在解密时获取并提供该密码。

解决这些问题并不一定能解决所有问题,但应该会引导您走向正确的方向。看一下右侧的一些相关问题.. StackOverflow 有许多可用的 AES 示例。

关于AES 加密期间出现 javax.crypto.BadPaddingException 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36991956/

相关文章:

java - 如何使用java程序设置类路径而不从命令行设置它?

java - JAX-RS/ Jersey : How can I "inherit" @Provider fields?

c - AES(aes-cbc-128、aes-cbc-192、aes-cbc-256)加密/解密,无需 openssl C

c++ - AES 加密/解密文本

Android + exoplayer : play AES encrypted videos, 本地

java - AES 加密 256 ECB 模式

java - "precise rethrow with a final exception"在 Java SE 8 中工作吗?

database - 在由第三方管理员管理/控制的服务器上保护 SQL Server 数据库

.net - 在共享主机上加密 web.config

c - ARM 和 Intel 内部函数是否对 AES 使用相同的子 key 计划?