2015-04-06 26 views
0

我已经存储密码的类(我将不仅仅是密码才能加入更多的东西)称为数据: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库,然后下载和使用其他人。

+3

我建议不要存储密码。最好存放它们的哈希值。这允许您验证输入的密码是否正确,而不需要以可用于在合理时间内恢复它们的格式存储它们。 –

+1

是的,只需对密码进行加密,就可以通过社交工程和反向工程代码等“软”手段恢复密码。没有负责任的网站存储密码,无论是否加密。你把它们打散 - 用一个好的,腌制的,难以记忆的散列 - 并存储它。这样,你甚至无法在传票或酷刑下泄露密码。 –

+0

@LeeDanielCrocker如果在运行时被问到,使用散列还可以更改密码吗? – FOD

回答

1

不通过ObjectOutputStream。您必须使用加密库并加密完整文件或密码。

0

在读写对象时,您可以让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在评论中指出的那样,您可能会考虑只是对密码进行哈希处理而不是将其存储起来。

+1

您还必须将密码定义为瞬态。 – EJP

+0

我不确定为什么你想要这样做,如果目的是加密其价值。将其标记为暂态将标记变量不被序列化,而不是在序列化过程中实际加密变量的值 – copeg

2

这取决于你的意思是“不可读”。如果您的目标是阻止恶意人员提取密码,即使他们拥有运行程序的必要权限,您也很难这么做。毕竟,如果一个程序可以解密密码,那么具有相同权限的人也可以。即使没有适当的权限,恶意用户也可能会检查内存中的原始字节,并在能够访问机器时提取密码。另一方面,如果你可以合理地信任用户,但只是想避免他们意外地以明文形式看到密码,任何简单的方案都可以工作;即使只是序列化字符串,因为它的十六进制码值就足够了。

如果您需要本身存储密码,即您正在访问需要密码的第三方服务,则必须锁定机器并将其访问权限制在绝对可信的人员身上。这是没有办法的。有a number of resources描述encrypting passwords,但他们都依赖于你能够锁定系统的某些部分的用户,通常是加密密钥或密码文本。

但是您可能不需要,也不应该实际上存储密码。验证用户的标准方法是从不存储其密码,而是存储密码的one-way hash。这(理论上)是不可能解密回原始密码的,但是通过对用户登录时输入的密码进行哈希处理,并将其与您拥有的哈希文件进行比较,您可以在不知道密码是什么的情况下验证其身份。

编辑:关于需要存储实际密码的系统还有一件事。除了锁定机器外,您还需要创建一个可靠的审计线索,以记录所有访问密码的尝试。应该记录和跟踪与该机器及其数据的每次交互,以便在出现问题时检查您的审计历史并了解问题的范围。如果你没有审计线索,你必须假设你的系统完全被破坏,因为你没有任何相反的证据。

0

您可以尝试编码/解码您的内容。您可以使用MD5散列函数。有预先写好的功能,它的使用非常简单。

以下链接可以帮助您了解如何在代码中使用它。 http://www.asjava.com/core-java/java-md5-example/

+0

以阐明:可以_encrypt/decrypt_,**或**一个可以_hash_,但不能使用MD5(散列函数)“编码/解码”;哈希函数在设计上是单向的,而且是不可逆的 – fspinnenhirn

相关问题