Java 尝试删除我附加到字节[](即IV)上的最后16个字节,然后解密
这是我的加密类:Java 尝试删除我附加到字节[](即IV)上的最后16个字节,然后解密,java,arrays,encryption,aes,Java,Arrays,Encryption,Aes,这是我的加密类: 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(
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。我目前得到的错误是:
java.lang.IllegalArgumentException:IV缓冲区对于给定的偏移量/长度组合太短
除了产生错误的问题之外,我的逻辑正确吗?这样行吗
我生成了一个16字节长的IV,并将其附加到加密文件的末尾
不,你没有。你预先准备好了。无论如何,这是个更好的主意。因此,您必须首先读取它,然后构造密码
和密码输入流
,并解密文件输入流的其余部分。您无需将整个文件读入内存即可完成以下操作:
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();
}
我生成了一个16字节长的IV,并将其附加到加密文件的末尾
不,你没有。你预先准备好了。无论如何,这是个更好的主意。因此,您必须首先读取它,然后构造密码
和密码输入流
,并解密文件输入流的其余部分。您无需将整个文件读入内存即可完成以下操作:
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();
}
如果静脉注射是在开始的话,我怎么把两者分开呢。通过
FileInputStream
读取前16个字节,然后将相同的FileInputStream
传递给cipheriputstream
。您能举个例子吗?我总是出错。这是一个漫长的一天盯着同一个代码。如果静脉注射是在一开始,我该如何区分这两个?我说的方式。通过FileInputStream
读取前16个字节,然后将相同的FileInputStream
传递给cipheriputstream
。您能举个例子吗?我总是出错。这是一个漫长的一天盯着相同的代码。