[英]CipherInputStream only read 16 bytes (AES/Java)
I'm using CipherInputStream and CipherOutputStream to encrypt files using AES. 我正在使用CipherInputStream和CipherOutputStream来使用AES加密文件。
encrypt(...)
seems to be working fine, but my decrypt(...)
function only decrypt the first 16 bytes of my files. encrypt(...)
似乎工作正常,但我的decrypt(...)
函数只解密我的文件的前16个字节。
Here is my class : 这是我的班级:
public class AESFiles {
private byte[] getKeyBytes(final byte[] key) throws Exception {
byte[] keyBytes = new byte[16];
System.arraycopy(key, 0, keyBytes, 0, Math.min(key.length, keyBytes.length));
return keyBytes;
}
public Cipher getCipherEncrypt(final byte[] key) throws Exception {
byte[] keyBytes = getKeyBytes(key);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, "AES");
IvParameterSpec ivParameterSpec = new IvParameterSpec(keyBytes);
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
return cipher;
}
public Cipher getCipherDecrypt(byte[] key) throws Exception {
byte[] keyBytes = getKeyBytes(key);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, "AES");
IvParameterSpec ivParameterSpec = new IvParameterSpec(keyBytes);
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
return cipher;
}
public void encrypt(File inputFile, File outputFile, byte[] key) throws Exception {
Cipher cipher = getCipherEncrypt(key);
FileOutputStream fos = null;
CipherOutputStream cos = null;
FileInputStream fis = null;
try {
fis = new FileInputStream(inputFile);
fos = new FileOutputStream(outputFile);
cos = new CipherOutputStream(fos, cipher);
byte[] data = new byte[1024];
int read = fis.read(data);
while (read != -1) {
cos.write(data, 0, read);
read = fis.read(data);
System.out.println(new String(data, "UTF-8").trim());
}
cos.flush();
} finally {
fos.close();
cos.close();
fis.close();
}
}
public void decrypt(File inputFile, File outputFile, byte[] key) throws Exception {
Cipher cipher = getCipherDecrypt(key);
FileOutputStream fos = null;
CipherInputStream cis = null;
FileInputStream fis = null;
try {
fis = new FileInputStream(inputFile);
cis = new CipherInputStream(fis, cipher);
fos = new FileOutputStream(outputFile);
byte[] data = new byte[1024];
int read = cis.read(data);
while (read != -1) {
fos.write(data, 0, read);
read = cis.read(data);
System.out.println(new String(data, "UTF-8").trim());
}
} finally {
fos.close();
cis.close();
fis.close();
}
}
public static void main(String args[]) throws Exception {
byte[] key = "mykey".getBytes("UTF-8");
new AESFiles().encrypt(new File("C:\\Tests\\secure.txt"), new File("C:\\Tests\\secure.txt.aes"), key);
new AESFiles().decrypt(new File("C:\\Tests\\secure.txt.aes"), new File("C:\\Tests\\secure.txt.1"), key);
}
}
So my question is, why the decrypt
function only read the first 16 bytes ? 所以我的问题是,为什么
decrypt
函数只读取前16个字节?
This is very subtle. 这非常微妙。 Your problem is that you are closing your
fos
before your cos
. 你的问题是你在
cos
之前关闭你的fos
。 In your encrypt(...)
method you are doing: 在您正在执行的
encrypt(...)
方法中:
} finally {
fos.close();
cos.close();
fis.close();
}
That closes the FileOutputStream
out from under the CipherOutputStream
so the final padded block of encrypted output never gets written to the output file. 这会从
CipherOutputStream
下面关闭FileOutputStream
,因此加密输出的最终填充块永远不会写入输出文件。 If you close the fos
after the cos
then your code should work fine. 如果你在
cos
后关闭fos
那么你的代码应该可以正常工作。
Really, you should consider doing something like: 真的,你应该考虑这样做:
FileOutputStream fos = null;
CipherOutputStream cos = null;
FileInputStream fis = null;
try {
fis = new FileInputStream(inputFile);
fos = new FileOutputStream(outputFile);
cos = new CipherOutputStream(fos, cipher);
// once cos wraps the fos, you should set it to null
fos = null;
...
} finally {
if (cos != null) {
cos.close();
}
if (fos != null) {
fos.close();
}
if (fis != null) {
fis.close();
}
}
FYI: org.apache.commons.io.IOUtils
has a great closeQuietly(...)
method which handles null
checks and catches the exceptions for you. 仅供参考:
org.apache.commons.io.IOUtils
有一个很好的closeQuietly(...)
方法,可以处理null
检查并为您捕获异常。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.