我有一个问题是读取文件(例如* .zip)并使用3DES加密它,使用secretKey,其中一个是从加密文件的名称生成的。 然后我需要解密这个文件,然后把它写在硬盘上。 我试图解决这个问题,但在解密文件时卡住了。
这是加密器的代码
public class Encryptor {
private static String inputFilePath = "D:/1.txt";
public static void main(String[] args) {
FileOutputStream fos = null;
File file = new File(inputFilePath);
String keyString = "140405PX_0.$88";
String algorithm = "DESede";
try {
FileInputStream fileInputStream = new FileInputStream(file);
byte[] fileByteArray = new byte[fileInputStream.available()];
fileInputStream.read(fileByteArray);
for (byte b : fileByteArray) {
System.out.println(b);
}
SecretKey secretKey = getKey(keyString);
Cipher cipher = Cipher.getInstance(algorithm);
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
ObjectOutputStream objectOutputStream = new ObjectOutputStream
(new CipherOutputStream
(new FileOutputStream
("D:/Secret.file"), cipher));
objectOutputStream.writeObject(fileByteArray);
objectOutputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public static SecretKey getKey(String message) throws Exception {
String messageToUpperCase = message.toUpperCase();
byte[] digestOfPassword = messageToUpperCase.getBytes();
byte[] keyBytes = Arrays.copyOf(digestOfPassword, 24);
SecretKey key = new SecretKeySpec(keyBytes, "DESede");
return key;
}
}
这是解密者的代码
public class Decryptor {
public static void main(String[] args) {
try {
File inputFileNAme = new File("d:/Secret.file");
FileInputStream fileInputStream = new FileInputStream(inputFileNAme);
FileOutputStream fileOutputStream = new FileOutputStream(outputFilePath);
SecretKey secretKey = getKey(keyString);
Cipher cipher = Cipher.getInstance(algorithm);
cipher.init(Cipher.DECRYPT_MODE, secretKey);
ObjectInputStream objectInputStream = new ObjectInputStream
(new CipherInputStream(fileInputStream, cipher));
System.out.println(objectInputStream.available());
while (objectInputStream.available() != 0) {
fileOutputStream.write((Integer) objectInputStream.readObject());
System.out.println(objectInputStream.readObject());
}
fileOutputStream.flush();
fileOutputStream.close();
fileInputStream.close();
objectInputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public static SecretKey getKey(String message) throws Exception {
String messageToUpperCase = message.toUpperCase();
byte[] digestOfPassword = messageToUpperCase.getBytes();
byte[] keyBytes = Arrays.copyOf(digestOfPassword, 24);
SecretKey key = new SecretKeySpec(keyBytes, "DESede");
return key;
}
}
当我尝试解密我的文件时,我在输出文件中没有任何内容
我尝试make debug,看到objectInputStream.available()
总是包含0
请告诉我,我该如何解决这个问题,以及为什么会这样。
答案 0 :(得分:2)
用法
byte[] fileByteArray = new byte[fileInputStream.available()];
是specifically warned against in the Javadoc:"使用此方法的返回值来分配用于保存此流中所有数据的缓冲区是绝对正确的。"
文件应该一次处理一个记录或一个缓冲区。
该行:
fileInputStream.read(fileByteArray);
不保证填充缓冲区。您必须检查返回值:for -1,表示文件结尾,或者> 0,表示实际传输的字节数。见Javadoc。
类似地
while (objectInputStream.available() != 0) {
不是流结束的有效测试。您应该致电readObject()
,直到它抛出EOFException.
答案 1 :(得分:1)
作为quickfix,这有效:
try {
File inputFileNAme = new File("d:/Secret.file");
FileInputStream fileInputStream = new FileInputStream(inputFileNAme);
FileOutputStream fileOutputStream = new FileOutputStream(outputFilePath);
SecretKey secretKey = getKey(keyString);
Cipher cipher = Cipher.getInstance(algorithm);
cipher.init(Cipher.DECRYPT_MODE, secretKey);
ObjectInputStream objectInputStream = new ObjectInputStream
(new CipherInputStream(fileInputStream, cipher));
System.out.println(objectInputStream.available());
fileOutputStream.write((byte[]) objectInputStream.readObject());
fileOutputStream.flush();
fileOutputStream.close();
fileInputStream.close();
objectInputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
我所做的是删除" .available()
while循环"并将演员表移至错误的Integer
。
我同意EJP的答案,特别是关于.available()
的使用。
您也可以使用http://www.jasypt.org/为crytpo提供更简单的API。