Java:如何使对象写入文件对人类来说是不可读的?
我已经存储密码的类(我将不仅仅是密码才能加入更多的东西)称为数据:Java:如何使对象写入文件对人类来说是不可读的?
import java.io.Serializable;
public class Data implements Serializable{
public String password = "";
}
作为测试我跑这两个:
private static File datafile = new File("data.src");
public static void checkDatafile() {
try {
Data data = new Data();
data.password = "Newwww";
if (!datafile.exists()) {
datafile.createNewFile();
ObjectOutputStream oos = new ObjectOutputStream(
new FileOutputStream(datafile));
oos.writeObject(data);
oos.flush();
oos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
public static Data loadData(Data data) {
try {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(datafile));
data = (Data) ois.readObject();
ois.close();
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
return data;
}
它写入和读取完美,但是当我在记事本中打开它data.src人类是便于阅读的密码是不是安全的,这是data.src的输出:
ャ・ sr data.Data克ラ淕6J・ L passwordt Ljava/lang/String;xpt Newwww
密码很容易看到并且不安全,在写入文件时有没有办法对对象进行加密/编码以便人类无法读取?
此外,我宁愿坚持标准的Java库,然后下载和使用其他人。
不通过ObjectOutputStream
。您必须使用加密库并加密完整文件或密码。
在读写对象时,您可以让Data类实现writeObject/readObject方法来加密/解密密码。
private void writeObject(ObjectOutputStream os) throws IOException{
password = encrypt(password);
os.defaultWriteObject();
}
private void readObject(ObjectOutputStream os) throws IOException{
os.defaultReadObject();
password = decrypt(password);
}
在加密/解密定义你想使用的ecryption/decryption算法。正如GregorRaýman在评论中指出的那样,您可能会考虑只是对密码进行哈希处理而不是将其存储起来。
这取决于你的意思是“不可读”。如果您的目标是阻止恶意人员提取密码,即使他们拥有运行程序的必要权限,您也很难这么做。毕竟,如果一个程序可以解密密码,那么具有相同权限的人也可以。即使没有适当的权限,恶意用户也可能会检查内存中的原始字节,并在能够访问机器时提取密码。另一方面,如果你可以合理地信任用户,但只是想避免他们意外地以明文形式看到密码,任何简单的方案都可以工作;即使只是序列化字符串,因为它的十六进制码值就足够了。
如果您需要本身存储密码,即您正在访问需要密码的第三方服务,则必须锁定机器并将其访问权限制在绝对可信的人员身上。这是没有办法的。有a number of resources描述encrypting passwords,但他们都依赖于你能够锁定系统的某些部分的用户,通常是加密密钥或密码文本。
但是您可能不需要,也不应该实际上存储密码。验证用户的标准方法是从不存储其密码,而是存储密码的one-way hash。这(理论上)是不可能解密回原始密码的,但是通过对用户登录时输入的密码进行哈希处理,并将其与您拥有的哈希文件进行比较,您可以在不知道密码是什么的情况下验证其身份。
编辑:关于需要存储实际密码的系统还有一件事。除了锁定机器外,您还需要创建一个可靠的审计线索,以记录所有访问密码的尝试。应该记录和跟踪与该机器及其数据的每次交互,以便在出现问题时检查您的审计历史并了解问题的范围。如果你没有审计线索,你必须假设你的系统完全被破坏,因为你没有任何相反的证据。
您可以尝试编码/解码您的内容。您可以使用MD5散列函数。有预先写好的功能,它的使用非常简单。
以下链接可以帮助您了解如何在代码中使用它。 http://www.asjava.com/core-java/java-md5-example/
以阐明:可以_encrypt/decrypt_,**或**一个可以_hash_,但不能使用MD5(散列函数)“编码/解码”;哈希函数在设计上是单向的,而且是不可逆的 – fspinnenhirn
我建议不要存储密码。最好存放它们的哈希值。这允许您验证输入的密码是否正确,而不需要以可用于在合理时间内恢复它们的格式存储它们。 –
是的,只需对密码进行加密,就可以通过社交工程和反向工程代码等“软”手段恢复密码。没有负责任的网站存储密码,无论是否加密。你把它们打散 - 用一个好的,腌制的,难以记忆的散列 - 并存储它。这样,你甚至无法在传票或酷刑下泄露密码。 –
@LeeDanielCrocker如果在运行时被问到,使用散列还可以更改密码吗? – FOD