试图删除我附加到字节[](是IV)然后解密的最后16个字节



这是我的加密类:

public static void encrypt(byte[] file, String password, String fileName, String dir) throws Exception {
    SecureRandom r = new SecureRandom();
    //128 bit IV generated for each file
    byte[] iv = new byte[IV_LENGTH];
    r.nextBytes(iv);
    IvParameterSpec ivspec = new IvParameterSpec(iv);
    SecretKeySpec keySpec = new SecretKeySpec(password.getBytes(), "AES");
    Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
    cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivspec);
    FileOutputStream fos = new FileOutputStream(dir + fileName);
    fos.write(iv);
    CipherOutputStream cos = new CipherOutputStream(fos, cipher);
    // Have to append IV --------
    cos.write(file);
    fos.flush();
    cos.flush();
    cos.close();
    fos.close();
}

这是我的解密方法:

public static void decrypt(byte[] file, String password, String fileName, String dir) throws Exception
{   
    // gets the IV
    int ivIndex = file.length - 16;
    byte[] truncatedFile = Arrays.copyOfRange(file, 0, file.length - 16);
    SecretKeySpec keySpec = new SecretKeySpec(password.getBytes(), "AES");
    Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
    cipher.init(Cipher.DECRYPT_MODE, keySpec, new IvParameterSpec(truncatedFile, ivIndex, 16));
    //IvParameterSpec ivspec = new IvParameterSpec(iv);
    //
    //cipher.init(Cipher.DECRYPT_MODE, keySpec, ivspec);
    FileOutputStream fos = new FileOutputStream(dir + fileName);
    CipherOutputStream cos = new CipherOutputStream(fos, cipher);
    cos.write(file);
    fos.flush();
    cos.flush();
    cos.close();
    fos.close();
}

}

您可以看到,我生成了一个16个字节长IV,该长IV已将其附加到加密文件的末尾。这样我就可以脱离IV进行解密,并且每个文件都具有独特的IV。我目前正在遇到错误:

java.lang.IllegalArgumentException:IV缓冲区太短,用于给定偏移/长度组合

除了产生错误的问题外,我的逻辑正确吗?这个可以工作吗?

我生成了一个16个字节长IV,我已将其附加到加密文件的末尾。

不,你没有。您 pre - 对其进行了限制。无论如何,这是一个更好的主意。因此,您必须先读取它,然后构造您的CipherCipherInputStream并解密文件输入流的其余部分。您无需将整个文件读取到内存即可完成:

public static void decrypt(File file, String password) throws Exception
{
    byte[] iv = new byte[16];
    DataInputStream dis = new DataInputStream(new FileInputStream(file));
    dis.readFully(iv);
    SecretKeySpec keySpec = new SecretKeySpec(password.getBytes(), "AES");
    Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
    cipher.init(Cipher.DECRYPT_MODE, keySpec, new IvParameterSpec(iv));
    CipherInputStream cis = new CipherInputStream(dis, cipher);
    // Now just read plaintext from `cis` and do whatever you want with it.
    cis.close();
}

相关内容

最新更新