我不是Java开发人员,但我的客户已经雇用了一个更新其网站上的一些JAR文件。在此之前,我们审核了现有代码并发现了许多安全漏洞。我们用于使文件更安全的解决方案之一是创建一个对数据库具有只读访问权限的新数据库用户,并且仅针对JAR文件需要运行的那些表。然后我发现他们将这些凭证与JAR文件一起存储在纯文本文件中,只是远离公众的教育猜测。最后,今天他们要求更宽松的数据库权限,但我认为她并不理解她真的不应该为正确编写的JAR文件需要它们。
无论如何,我很确定这个开发人员如果把它放在背后,就不会知道安全漏洞。我对Java / JAR文件不够了解,无法正确地告诉她应该做什么,只有infosec告诉她不应该是什么做。
那么在编写连接到远程MySQL数据库的分布式JAR文件时,典型的安全注意事项是什么?是否有加密连接详细信息(用户名和/或密码)的标准方法? IIRC,不是.jar文件只是美化ZIP档案,并且没有任何人可以解压缩文件并查看源代码中的连接细节?有没有办法加密jar文件内容?
更新:我收到了开发人员的以下说明。听起来不错吗?
jar文件中的所有类都是加密的。我总是加密所有类文件,然后将它们存档在一个jar文件中。如果您打开任何[编辑] jar,您将只看到加密代码。因此,用户无法通过反编译来查看源代码。这些类确实使用jdbc连接到db,搜索eangine需要连接到DB才能运行sqls。这些sql是jar文件中的加密clase。
当我问你关于加密数据库密码时,我的意思是你在下面说的。我们将在java中编写加密/解密代码并使用它。来自此源代码的编译类将再次作为reoutine类加密过程的一部分进行加密。我们使用名为Retroguard的Java混淆工具来加密所有类。我们还在html页面中嵌入了一个密钥,以确保只有在[编辑]网站下载后才能使用该应用程序。如果用户将jar复制到本地计算机并尝试运行它,它将失败。
答案 0 :(得分:3)
是的,JAR只是ZIP文件,因此完全可以使用WinZip打开它并查看内容。如果您知道自己在做什么,可以在里面找到明文密码。
听起来您的JAR包含直接连接到数据库的客户端。您没有说这是通过Internet还是VPN或LAN完成的。数据库是从客户端远程部署的吗?
这就是客户端/服务器应用程序消失的原因之一:很难通过Internet保护它们。
您的应用听起来像我的经典客户端服务器。我有这个权利吗?
通常在客户端和数据库之间引入中间层,以检查安全性,验证和绑定输入,以及将请求传递到适当的处理程序以进行实现。让用户在将中间层传递给数据库之前提供中间层必须验证的凭据。
它还可以帮助您抵御SQL注入攻击。
如果加密JAR内容,则必须编写自定义类加载器以在加载时解密它们。不适合胆小的人。
如果您的客户端是Swing应用程序,并且为每个组件注册了监听器和事件处理程序中内置的所有逻辑和数据库内容,那么您将完全重写。您将转向更多面向服务的体系结构,其中所有工作都由服务器端的服务完成。客户端只在经典MVC中执行它应该做的事情:将事件传递到服务器端并显示结果。你的客户会更轻松。
这将是您的开发团队和业务的最大冲击。
答案 1 :(得分:2)
我将通过陈述经常陈述的内容开始我的回答:“任何人都可以创建一个他/她无法破解的安全计划。”
现在,请注意在同一更新中提及加密和模糊处理的更新,明智的是要注意加密与模糊处理不同。从技术上讲,加密涉及使用密钥将一些明文转换为密文,明文只有在知道原始密钥的情况下才能恢复。根据定义,混淆与加密无关 - 它涉及从可执行源代码中删除信息,这使得可执行文件被认为“难以”进行逆向工程。通常,混淆涉及用较小的符号替换符号,有时重新排序使反向工程源代码难以读取的源代码,同时保留原始的执行配置文件(混淆的源代码具有相同的代码和数据流路径)作为原始)。
这里重要的是,密码被编码到源代码中。假设混淆的源代码还包含硬编码密码是合理的。这个假设是合理的,因为大多数混淆器从未试图改变constant pool within a class file - 改变常量池是危险的,因为它可能导致运行时行为的改变。如果密码已经作为字符串硬编码到源代码中,则类文件(模糊或未模糊)将具有String constant pool中的密码,该密码将由JVM加载到内存中(不进行解密)或其间的解码过程。)
这种情况下的最佳做法是让最终用户指定数据库用户ID和密码(如果他们正在管理应用程序设置),以安全地存储这些用户提供的凭据(这取决于数据库的性质)应用程序; Java EE应用程序应尝试让容器管理这些凭据),并在从安全存储中检索这些凭据时安全地管理这些凭据。您可能需要查看Insecure Storage上的OWASP文章以获取更多指示。
鉴于使用applet,建议不要在applet中使用数据库用户ID和密码。这需要由于各种原因而完成 - 良好的应用程序允许仅通过对应用程序的配置更改来更改数据库用户ID和密码。在源代码中对密码进行硬编码势必会增加管理开销;每次DBA选择更改密码时,您可能必须让最终用户清除其Java小程序缓存(这有时会在理智的数据中心中发生)。此外,在部署对applet的更改时,您可能还需要防止数据库帐户锁定。与发布的其他建议一样,从中间层管理数据库连接将具有很大的商业意义。
答案 2 :(得分:0)
我认为大多数开发人员对此类事情的约定是将配置文件存储在Web目录的根目录之外。当然,如果这是一个桌面应用程序,而不是不可能的网络。我之前在基于SWING的MySQL驱动应用程序中使用有限数量的用户所做的事情不是使用中间层进行身份验证并使用MySQL的内置身份验证将数据呈现为服务,因此所有安全性都将在架构,然后为每个用户复制权限设置。一种hackish但可靠的方法。
答案 3 :(得分:-1)
用简单的文字说(我认为)是非常脆弱的。实际上,人们可以提取jar并阅读那些纯文本中的内容。
如果使用jar是必须的,我建议创建一个类(只是一个简单的类),其中包含带有final关键字的用户名,密码,url等。即使这种方法不是很安全,但至少不能轻易读取编译的类。另一个优点(或可能是缺点)是“硬编码”连接属性不容易修改。即使你有源代码,你仍然需要重新编译它并重新制作它。