我正在尝试使用DES算法加密file.txt。我必须将生成的密钥保存在没有扩展名的文件中。我认为这部分很好地解决了。但是我使用相同的密钥解密加密文件很麻烦。我收到错误:“给定最后一个块没有正确填充”。
练习: 1.加密程序:读取文本文件,使用DES算法对其进行加密,并将结果写入新文件,另一个文件存储在用于加密的密钥中。 2.解密程序:读取加密密钥保存的程序,解密加密程序存储的文本并将其显示在屏幕上。
注意:使用FileInputStream和FileOutputStream,以8字节为单位执行加密,并以16字节为单位执行解密。
密钥加密
import java.io.*;
import javax.crypto.*;
import javax.crypto.spec.*;
public class Encrypt {
public static void main(String[] args) {
try {
SecretKey key = KeyGenerator.getInstance("DES").generateKey();
FileOutputStream fosKey = new FileOutputStream("..\\KEY");
SecretKeyFactory keyfac = SecretKeyFactory.getInstance("DES");
DESKeySpec keyspec = (DESKeySpec) keyfac.getKeySpec(key, DESKeySpec.class);
fosKey.write(keyspec.getKey());
fosKey.close();
Cipher crypt = Cipher.getInstance("DES");
crypt.init(Cipher.ENCRYPT_MODE, key);
FileInputStream fis = new FileInputStream("..\\File.txt");
FileOutputStream fos = new FileOutputStream("..\\FileCrypted.txt");
byte[] arrayBytes = new byte[8];
int bytesReads;
while ((bytesReads = fis.read(arrayBytes)) != -1) {
fos.write(crypt.doFinal(arrayBytes), 0, bytesReads);
}
fis.close();
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
解密
import java.io.*;
import javax.crypto.*;
import javax.crypto.spec.*;
public class Decrypt {
public static void main(String[] args) {
try {
FileInputStream fisKey = new FileInputStream("..\\KEY");
byte[] arrayKey = new byte[fisKey.available()];
fisKey.read(arrayKey);
SecretKey key = new SecretKeySpec(arrayKey, "DES");
Cipher decrypt = Cipher.getInstance("DES");
decrypt.init(Cipher.DECRYPT_MODE, key);
FileInputStream fis = new FileInputStream("..\\FileCrypted.txt");
byte[] encText = new byte[16];
int bytesReads;
while ((bytesReads = fis.read(encText)) != -1) {
fis.read(decrypt.doFinal(encText), 0, bytesReads);
}
fis.close();
System.out.println(new String(encText));
} catch (Exception e) {
e.printStackTrace();
}
}
}
答案 0 :(得分:2)
您应该使用update()
方法进行中间加密调用,并且仅在最后一次调用时使用doFinal()
。这适用于加密和解密。
DES - 在ECB或CBC模式下 - 总是使用 8字节的块大小(加密和解密)。如果填充处于活动状态,则会附加其他数据(1-8字节),以确保在执行doFinal()
时块大小为8。如果密码上的填充未激活,则需要确保在执行doFinal()
时数据已提供为8个字节的倍数。
update()
允许您处理加密数据而不与8字节块大小对齐,因为它只是缓存直到它有完整块的数据。 doFinal()
刷新缓冲区中可能存在的任何过多字节以进行加密,并应用任何可能有效的填充。
请注意,DES 不再被视为安全,因此不应将其用于任何严重的安全措施。