我在 java 中有一个属性文件,其中存储了我的应用程序的所有信息,例如徽标图像文件名、数据库名称、数据库用户和数据库密码。
我可以将加密的密码存储在属性文件中。但是,可以使用反编译器从 jar 中读取密钥或密码。
有没有办法将 db pass 安全地存储在属性文件中?
我在 java 中有一个属性文件,其中存储了我的应用程序的所有信息,例如徽标图像文件名、数据库名称、数据库用户和数据库密码。
我可以将加密的密码存储在属性文件中。但是,可以使用反编译器从 jar 中读取密钥或密码。
有没有办法将 db pass 安全地存储在属性文件中?
有多种方法可以管理这一点。如果您能找到一种方法让用户在应用程序启动时为密钥库提供密码,那么最合适的方法是使用密钥加密所有值,并将此密钥存储在密钥库中。密钥库的命令行界面是使用 keytool。然而,JSE 也有 API 以编程方式访问密钥库。
如果您无法让用户在启动时手动向密钥库提供密码(例如对于 Web 应用程序),那么一种方法是编写一个异常复杂的混淆例程,该例程可以混淆密钥并将其存储在还有一个属性文件。要记住的重要事项是,混淆和反混淆逻辑应该是多层的(可能涉及加扰、编码、引入虚假字符等),并且本身应该至少有一个可以隐藏在应用程序的其他类中的密钥使用不直观的名称。这不是一个完全安全的机制,因为拥有反编译器并且有相当多的时间和智慧的人仍然可以解决它,但它是我所知道的唯一一个不需要您闯入本机(即不易反编译)代码的机制.
您将密码的 SHA1 哈希值存储在属性文件中。然后,当您验证用户密码时,您会散列他们的登录尝试并确保两个散列匹配。
这是将为您散列一些字节的代码。getBytes()
您可以使用该方法轻松地从字符串中获取字节。
/**
* Returns the hash value of the given chars
*
* Uses the default hash algorithm described above
*
* @param in
* the byte[] to hash
* @return a byte[] of hashed values
*/
public static byte[] getHashedBytes(byte[] in)
{
MessageDigest msg;
try
{
msg = MessageDigest.getInstance(hashingAlgorithmUsed);
}
catch (NoSuchAlgorithmException e)
{
throw new AssertionError("Someone chose to use a hashing algorithm that doesn't exist. Epic fail, go change it in the Util file. SHA(1) or MD5");
}
msg.update(in);
return msg.digest();
}
不,那里没有。即使你加密它,也有人会反编译解密它的代码。
您可以为密码(直接数据库密码或密钥密码)创建一个单独的属性文件(在 jar 之外),并且不将该属性文件包含在分发中。或者您可以让服务器只接受来自特定机器的登录,这样就需要进行欺骗。
除了如上所述加密密码外,请将任何密码放在单独的属性文件中,并在部署时尝试为该文件提供尽可能多的锁定权限。
例如,如果您的应用程序服务器在 Linux/Unix 上运行,root
则将密码属性文件设置为root
具有 400/-r--------
权限。
当然,在以某种方式进行身份验证后,您不能让应用程序通过 https 联系服务器并下载密码吗?