我有一个类,它存储一个名为Data:的密码(我将添加比密码更多的东西)
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);
}
加密/解密定义您希望使用的加密/解密算法。话虽如此,正如Gregor Raýman在评论中所指出的,你可能会考虑只是对密码进行散列处理,而不是存储它们。
您可以尝试对内容进行编码/解码。您可以使用MD5散列函数。有一些预先编写好的函数,它的使用非常简单。
以下链接可以帮助您了解如何在代码中使用它。http://www.asjava.com/core-java/java-md5-example/