您好,我有以下问题:
我有一个可序列化的类/对象访问。
public class Access implements Serializable {
private static final long serialVersionUID = 1L;
private URL website;
private String username;
private String password;
// + some methods
}
现在,当将它们写入文件时,我使用密码对它们进行加密。看起来像这样:
写作:
ObservableList<Access> userData;
userData = FXCollections.observableArrayList();
...
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, key128);
File file = new File("./resources/saves" + username);
file.createNewFile();
CipherOutputStream cipherOut = new CipherOutputStream(
new BufferedOutputStream(new FileOutputStream(file, true)), cipher);
ObjectOutputStream out = new ObjectOutputStream(cipherOut);
userData.forEach((item) -> {
try {
out.writeObject(new SealedObject(item, cipher));
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
});
out.flush();
out.close();
阅读:
ObservableList<Access> access = FXCollections.observableArrayList();
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, key128);
CipherInputStream cipherIn = new CipherInputStream(
new BufferedInputStream(new FileInputStream("./resources/saves" + username)), cipher);
ObjectInputStream in = new ObjectInputStream(cipherIn);
SealedObject sealed;
while ((sealed = (SealedObject) in.readObject()) != null) {
access.add((Access) sealed.getObject(cipher));
}
如果我现在加载文件,它似乎已损坏。我发现很难找到错误。我认为问题出在加载函数上。我在这里遗漏了一些明显的东西吗?
错误:
java.io.StreamCorruptedException: invalid stream header: 3D23898C
感谢您的时间和帮助! :*
最佳答案
好吧,问题是密码流和对象流之间的交互。
当您读取文件时,ObjectInputStream
会要求底层流(密码流)读取非常具体的 header 。但密码流对此的了解为零——根据他自己的协议(protocol),他读取了他应该读取的正常字节数,以便理解加密的数据。结果是 ObjectInputStream 获得截断/更改的 header ,并且无法正确处理流。
好消息是,您实际上并不需要它! SealedObject
将为您处理加密/解密。只需删除密码流就可以了。
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(file, true));
并阅读:
FileInputStream inputStream = new FileInputStream(fileName);
ObjectInputStream ois = new ObjectInputStream(inputStream);
现在,如果您确实想要使用密码流(从而使用相同的 key 有效地加密/解密数据两次),您需要首先对文件进行“第一次传递”解密它,然后在新的解密文件上打开对象流。
关于java读取加密对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42211257/