无效的密钥异常



我正在从文件中检索文本密码作为输入,并对其应用AES加密,然后再对其进行解密。当我第一次这样做时,每隔 4 次中有 5 次它运行正常(加密解密成功(,但 1 次,它抛出 BadPaddingException。以下是我写的:

//ABCD is class name
public static void enc(String fileName, String pwd) {
    try {
        Properties prop = new Properties();
        InputStream input = ABCD.class.getClassLoader().getResourceAsStream(fileName);
        prop.load(input);
        input.close();
        URL url = ABCD.class.getClassLoader().getResource(fileName);
        FileOutputStream outputStream = new FileOutputStream(url.getPath());
        KeyGenerator key = KeyGenerator.getInstance("AES");
        key.init(128);
        SecretKey aesKey = key.generateKey();
        String newkey = new  String(Base64.encode(aesKey.getEncoded()).getBytes("UTF-8"));
        Cipher aesCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        aesCipher.init(Cipher.ENCRYPT_MODE, aesKey);
        byte[] clear = pwd.getBytes("UTF-8");
        byte[] cipher = aesCipher.doFinal(clear);
        String encPwd = new String(cipher);
        prop.setProperty("password", encPwd);
        prop.setProperty("secKey", newkey);
        prop.store(outputStream, null);
        outputStream.close();
    } catch (Exception e) {
        System.out.println(e);
    }
}
public static String dec(Properties prop, String fileName) {
    String decPwd = ABCD.map.get(fileName);
            try {
            String newkey = prop.getProperty("secKey");
            StringBuilder pwd;
            byte[] newkeybuff = Base64.decode(newkey.getBytes("UTF-8"));
            SecretKey key = new SecretKeySpec(newkeyuff, "AES");
            Cipher aesCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            aesCipher.init(Cipher.DECRYPT_MODE, key);
            pwd = new StringBuilder(prop.getProperty("password"));
            byte[] cipher = aesCipher.doFinal(pwd.toString().getBytes());
            decPwd = new String(cipher);
        } catch (Exception e) {
            System.out.println(e);
        }
        ABCD.map.put(fileName, decPwd);
    return decPwd;
}

我需要解决这个问题。在某处,我读到BadPaddingExcpetion发生在使用String完成的操作之后,而不是实际应该使用字节的位置。因此,我将代码更改为以下内容:

public static void enc(String fileName, String pwd) {
    try {
        Properties prop = new Properties();
        InputStream input = ABCD.class.getClassLoader().getResourceAsStream(fileName);
        prop.load(input);
        input.close();
        URL url = ABCD.class.getClassLoader().getResource(fileName);
        FileOutputStream outputStream = new FileOutputStream(url.getPath());
        KeyGenerator key = KeyGenerator.getInstance("AES");
        key.init(128);
        SecretKey aesKey = key.generateKey();
        byte[] newkey=(Base64.encode(aesKey.getEncoded())).getBytes("UTF-8");
        Cipher aesCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

        aesCipher.init(Cipher.ENCRYPT_MODE, aesKey,new IvParameterSpec(new byte[16]));
        byte[] clear = pwd.getBytes("UTF-8");
        byte[] cipher = aesCipher.doFinal(clear);
        prop.setProperty("password", Arrays.toString(cipher));
        prop.setProperty("secKey", Arrays.toString(newkey));
        prop.store(outputStream, null);
        outputStream.flush();
        outputStream.close();
    } catch (Exception e) {
    System.out.println(e);
}
}
public static String dec(Properties prop, String fileName) {
    String decPwd = ABCD.map.get(fileName);
            try {
            byte[] newkey=prop.getProperty("secKey").getBytes("UTF-8");
            byte[] pwd;

            byte[] newkeybuff = Base64.decode(newkey);
            SecretKeySpec key = new SecretKeySpec(newkeybuff, "AES");
            Cipher aesCipher=Cipher.getInstance("AES/CBC/PKCS5Padding");
            aesCipher.init(Cipher.DECRYPT_MODE, key,new IvParameterSpec(new byte[16]));
            pwd = prop.getProperty("password").getBytes();
            byte[] cipher = aesCipher.doFinal(pwd);
            decPwd=new String(cipher);
            System.out.println("Decrypted pwd " + decPwd);
        } 
        catch (Exception e) {
    System.out.println(e);
}
        ABCD.map.put(fileName, decPwd);
    return decPwd;
}

现在,我得到无效密钥异常。这次,我读到密钥的大小应该是 16 字节。但我不知道如何应用它。需要解决此问题!

您应该检查您的 IV(初始化向量(,该向量对于加密和解密必须相同。

填充

错误通常意味着解密失败。

检查密钥是否为全长(16

、24 或 32 字节(,IV 是否为全长(16 字节(。如果键或IV要做短,它将填充"某物"并且那个人不一致,这种填充没有标准。

getBytes("UTF-8")可能会返回不同的字节长度,具体取决于所使用的字符。

对 IV 使用 new IvParameterSpec(new byte[16]) 是不正确的,IV 应该是随机字节。处理 IV 的常用方法是在加密时创建一个随机 IV 并将其附加到加密数据之前,它不需要是秘密的,并且通过预置它将可用于解密。

相关内容

最新更新