Java 文件加密丢失字节
我正在尝试编写一个简单的程序来使用 AES 算法加密和解密文件。稍后的目的是在更复杂的程序中使用将简单程序拆分为加密和解密方法。 他是程序的加密部分:
KeyGenerator kg = KeyGenerator.getInstance("AES");
kg.init(128);
SecretKey key = kg.generateKey();
Cipher c = Cipher.getInstance("AES");
c.init(Cipher.ENCRYPT_MODE, key);
FileInputStream fis; FileOutputStream fos; CipherOutputStream cos;
fis = new FileInputStream("FileTo.encrypt");
fos = new FileOutputStream("Encrypted.file");
//write encrypted to file
cos = new CipherOutputStream(fos, c);
byte[] b = new byte[16];
int i = fis.read(b);
while (i != -1) {
cos.write(b, 0, i);
i = fis.read(b);
}
cos.close();
//write key to file
byte[] keyEncoded = key.getEncoded();
FileOutputStream kos = new FileOutputStream("crypt.key");
kos.write(keyEncoded);
kos.close();
这是解密部分:
//Load Key
FileInputStream fis2= new FileInputStream("a.key");
File f=new File("a.key");
long l=f.length();
byte[] b1=new byte[(int)l];
fis2.read(b1, 0, (int)l);
SecretKeySpec ks2=new SecretKeySpec(b1,"AES");
Cipher c1 = Cipher.getInstance("AES");
c1.init(Cipher.DECRYPT_MODE, ks2);
FileInputStream fis1=new FileInputStream("Encrypted.file");
CipherInputStream in= new CipherInputStream(fis1,c1);
FileOutputStream fos0 =new FileOutputStream("decrypted.file");
byte[] b3=new byte[1];
int ia=in.read(b3);
while (ia >=0)
{
c1.update(b3); //<-------remove this
fos0.write(b3, 0, ia);
ia=in.read(b3);
}
in.close();
fos0.flush();
fos0.close();
现在的问题是解密部分没有解密最后的位,有些位丢失了。在我看来,它只解密每 16 个字节,但变量 in(cipherinputstream) 在应该返回最后一个字节时返回 -1。 我如何获得最后几位?
提前致谢已
编辑:添加评论以指出必须删除的内容。下面是一些使用 AES 正确(即无需在 Java 中加载整个文件)加密和解密 Java 文件的代码。可以添加其他参数(填充等),但这是基本代码。
I'm trying to write a simple program to encrypt and decrypt files using the AES algortihm. The intention later is to use split the simple program into encryption and decrytion methods in a more complex program.
He is the encryption part of the program:
KeyGenerator kg = KeyGenerator.getInstance("AES");
kg.init(128);
SecretKey key = kg.generateKey();
Cipher c = Cipher.getInstance("AES");
c.init(Cipher.ENCRYPT_MODE, key);
FileInputStream fis; FileOutputStream fos; CipherOutputStream cos;
fis = new FileInputStream("FileTo.encrypt");
fos = new FileOutputStream("Encrypted.file");
//write encrypted to file
cos = new CipherOutputStream(fos, c);
byte[] b = new byte[16];
int i = fis.read(b);
while (i != -1) {
cos.write(b, 0, i);
i = fis.read(b);
}
cos.close();
//write key to file
byte[] keyEncoded = key.getEncoded();
FileOutputStream kos = new FileOutputStream("crypt.key");
kos.write(keyEncoded);
kos.close();
Here's the decryption part:
//Load Key
FileInputStream fis2= new FileInputStream("a.key");
File f=new File("a.key");
long l=f.length();
byte[] b1=new byte[(int)l];
fis2.read(b1, 0, (int)l);
SecretKeySpec ks2=new SecretKeySpec(b1,"AES");
Cipher c1 = Cipher.getInstance("AES");
c1.init(Cipher.DECRYPT_MODE, ks2);
FileInputStream fis1=new FileInputStream("Encrypted.file");
CipherInputStream in= new CipherInputStream(fis1,c1);
FileOutputStream fos0 =new FileOutputStream("decrypted.file");
byte[] b3=new byte[1];
int ia=in.read(b3);
while (ia >=0)
{
c1.update(b3); //<-------remove this
fos0.write(b3, 0, ia);
ia=in.read(b3);
}
in.close();
fos0.flush();
fos0.close();
Now the problem is the decryption part is not decrypting the last bits, some bits are missing. It seems to me that it only decrypts every 16 bytes, but the variable in(cipherinputstream) returns -1 when it should be returning the last bytes.
How do I get the last bits?
Thanks in advance
Edited: Added comment to point out what has to be removed. Here's some code to properly (i.e., without loading the entire file in java) encrypt and decrypt a file in Java using AES. It's possible to add additional parameters (padding, etc.) but here's the basic code.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您只需删除代码中的这一行即可正常工作:
由于您使用的是
CipherInputStream
,因此无需手动更新Cipher
。它会为你处理这个问题,并且通过调用它,你会干扰解密。另外,为了提高效率,您应该增加
byte[] b
和byte[] b3
数组的大小。通常 8192 是适合缓冲的大小。You just need to remove this line in your code and it'll work fine:
Since you're using a
CipherInputStream
you don't need to update theCipher
manually. It handles that for you, and by calling it you're interfering with the decryption.On a side note, for efficiency you should increase the size of your
byte[] b
andbyte[] b3
arrays. Typically 8192 is a good size for buffering.这是我挖掘的一些 DES 示例代码,可能会有所帮助......尤其是对 doFinal 的调用。
Here's some DES example code I dug up, which might be helpful... especially the calls to doFinal.