我必须在这个问题前面说,我知道在客户端应用程序中对密码进行硬编码是不好的做法,原因有很多。处理该问题还有其他问题。此问题的范围较窄,并假设验证凭据必须驻留在客户端应用程序的代码上,原因可能是您无法控制的一些原因。
如果某些方法比其他方法更好(例如:JPasswordField将密码存储在char数组而不是String中),并且如果您必须在Java应用程序中对其进行硬编码,那么您可以采取哪些措施来使其变得更难被抓了?
更新
应用程序的一个实例在远程PC上运行,最终用户具有管理员权限。凭据用于访问同一网络中的数据库,因此实际密码已经预先确定,必须在实际代码中手动输入。
答案 0 :(得分:6)
....如果您不得不在Java应用程序中对其进行硬编码,您可以采取哪些措施来使其更难获取?
首先,我会确保管理层负责做出这个错误决定的人充分意识到这是从根本上和不可靠的不安全 1 。< / p>
然后我可能会想到一些 naff 算法,它以晦涩的方式组装密码;例如通过构建两个字节数组并将它们XOR一起...并分发混淆的字节码。您可以做的最好的事情是让技能有限的人难以对代码中的密码进行反向工程。
(使用强大的算法加密密码无济于事,因为算法和解密密钥的选择都必须嵌入到您的代码中。实际上,您可以梦想的任何方案都可以通过使用调试器来解决在密码需要清除的位置设置断点。)
1 ......甚至Jon Skeet也无法确保安全。
如果某些方法比其他方式更好(例如:JPasswordField将密码存储在char数组而不是String中)...
我只想注意,使用char数组在JPasswordField等中保存密码的正常推理是为了防止坏人从核心转储或交换文件中读取密码。在这种情况下它不会真正有用,因为我们必须假设你应该担心的坏人是具有系统管理员访问权限的simeone。他或她将有足够的控制权将调试器连接到JVM并从char数组中捕获字节。
答案 1 :(得分:1)
作为一般准则,您不应存储密码(当然)。
如果您需要在运行时提供密码,最佳做法(例如,Jez Humble的Continous Delivery一书中提倡的)是在部署/启动时提供密码。这样,密码只能驻留在人们的头脑中,而不是位于某个不安全的文件中。
我不知道你的情况是否可行,但你应该以此为目标。
答案 2 :(得分:1)
我认为最不理想的解决方案是,如果您可以使用基于挑战的身份验证协议,其中包含随机元素。
这样,它不仅仅是密码,它也是使用密码生成正确响应的代码,需要进行逆向工程。
然后它也可以是双向身份验证,即您可以验证对方是否也使用相同的协议/算法并且也具有相同的密码。
最重要的是,密码永远不会通过网络发送,因此无法嗅探。
Diffie-Helman key exchange是一种广泛使用的协议,但如果您只想要默默无闻,而不是真正的安全性,那么您可以随时使用自己的简单实现。好吧,如果可以从字节码反编译和反向设计所有内容,那么真正的安全性显然无法实现,但无论如何......:)
答案 3 :(得分:1)
在客户端存储敏感数据非常不安全,特别是密码,因为.class文件可以很容易地反编译。你有没有考虑过涉及一些非对称加密的东西?像公钥/私钥对或类似的东西?
答案 4 :(得分:0)
我喜欢斯蒂芬的答案,但我会补充......
源代码的安全性也很重要。无论您使用什么方法来模糊密码,任何有权访问源的人都可以轻松地放置System.out.println(password)
并在使用它的地方捕获密码,或者在调试中运行代码并暂停代码以检查变量。
即使没有编译,任何有jar
访问权限的人都可以在调试模式下启动java程序并暂停使用密码的程序并使用源代码检查变量,但仍然可以使用罐子和一些工具。
您可能会考虑让程序在需要时(通过Web服务调用或其他任何方式)从安全服务器获取密码,并让该服务器使用防火墙仅允许某些IP访问它(如果IP的客户端机器是已知的)。它仍然不安全,但至少它是什么。
答案 5 :(得分:-1)
您可以散列密码,甚至可以根据需要加密密码。看看这篇文章它可能会有用。 Java - encrypt / decrypt user name and password from a configuration file