Java:如何使写入文件的对象对人类不可读



我有一个类,它存储一个名为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/

最新更新