当前位置: 首页 > 知识库问答 >
问题:

从JVM堆中删除密码

邵奇
2023-03-14

关于如何在Java代码中管理密码,有各种各样的问题和答案——例如,这里和这里。

讨论往往集中在使用< code>char[]而不是< code>String的优点上。

但是,如果是第三方库将密码存储在字符串中,有什么方法可以避免密码存储在JVM的堆中呢?

例如,在以下三种情况下,我认为密码将在JVM的生命周期内保留在堆中:

编辑-示例更新为与我的问题更相关:

// some values read in from a properties file, or similar:
String url = ...;
String user = ...;
String pw = ... ;
...
HikariDataSource ds = new HikariDataSource();
ds.setJdbcUrl(url);
ds.setUsername(user);
ds.setPassword(pw);
...

在上面的示例中,我的com.zaxxer.hikari.HikariDataSource对象在String中包含密码。我看不到在不丢失连接池的情况下为数据源空的方法。

例如,如果我创建一个JDBCSessionDataStoreFactory,那么org.eclipse.jetty.server.session.DatabaseAdaptor保留连接凭据,包括String中的密码。

在这种情况下,可以在org.apache.tomcat.util.descriptor.web中找到密码。ContextResource,如果我还选择使用该连接池,可能也位于org.apache.tomcat.dbcp.dbcp2.BasicDataSource

换句话说,敏感连接信息可以在JVM堆中的不同位置找到,无论我在代码中使用char数组以及在不再需要敏感数据时覆盖/清空敏感数据有多努力。我并不是说我的努力白费了——我仍然想尽我所能保护自己(例如用户的登录凭据)。但其他凭据(如数据库连接)似乎超出了我的控制。

对于这些情况,有什么解决方案或最佳实践吗?

共有1个答案

常永怡
2023-03-14

就像@Holger在评论中说的,任何可以读取文件系统中的堆内存和/或堆转储的东西都已经控制了服务器,所以试图隐藏密码在这一点上是没有用的。更好的办法是保护实际的服务器和其中的服务。

托马斯·波尔宁在下面的链接中给出了一个很棒的答案,但这是关键段落(突出我的):

所有这些都不适用于服务器应用程序,也不适用于处理具有不可忽视的实际价值的机密的客户端代码。如果恶意攻击者能够扫描RAM中的敏感数据,并且这些数据值得人类攻击者1到2分钟的明确关注,那么无论多少覆盖都救不了你。因此,在许多安全很重要的情况下,覆盖密码和密钥只是浪费精力,这给人一种安全感,但实际上并没有改善什么(尽管这可能很方便让审计员敬畏)。

https://security.stackexchange.com/a/75891/4667

 类似资料:
  • 问题内容: Python具有实现堆数据结构的模块,并且它支持一些基本操作(推送,弹出)。 如何从O(log n)中的堆中删除第i个元素?甚至可以使用还是必须使用另一个模块? 请注意,文档底部有一个示例:http : //docs.python.org/library/heapq.html ,它建议了一种可能的方法-这不是我想要的。我希望删除元素,而不仅仅是标记为已删除。 问题答案: 您可以很容易地

  • 好吧,所以我有点困惑该怎么处理这个。因此,我有了主活动,从那里可以启动一个活动到DegreePlan活动,从那里可以启动另一个活动到EditDegreeplan。我已经将EditDegreeplan设置为在Android清单中没有历史记录。问题是在他们保存EditDegreeplan后,它会启动一个活动到Degreeplan。因此,如果用户按下后退键,他们必须按两次才能再次进入主活动。我想摆脱它,

  • 我有一个密钥库,名为keystore。jks和意外添加了两个键。我必须使用键2制作一个签名的apk。因为我已经使用key2上传了一个apk,我想从keystore中删除Key1。jks。 签名的apk是使用Key1生成的,但我需要使用key2生成。 请帮帮我。提前谢谢。

  • 我来自C/C++背景,在这里一个进程内存分为: null 我想把我的注意力集中在这一点上,当我阅读JVM中的堆和堆栈时,我们是在谈论堆栈和堆的概念吗?并且整个JVM的实际内存驻留在堆上(这里指的是堆的C++概念)?

  • 问题内容: Java在Java 5中引入了带有泛型的类型擦除,因此它们可以在Java的旧版本上使用。这是兼容性的折衷。从那以后,我们就失去了兼容性–字节码可以在JVM的更高版本上运行,但不能在较早的版本上运行。这似乎是最糟糕的选择:我们丢失了类型信息,并且仍然无法在较旧版本上运行针对较新版本JVM编译的字节码。发生了什么? 具体来说,我是在问是否存在任何技术原因,导致无法在下一版JVM中删除类型擦

  • 在infinispan/jgroups上对集群解决方案进行了一些内部测试,并注意到过期的条目永远不符合GC的条件,这是因为过期收割机上有一个引用,而集群中有多个节点启用了过期/禁用了逐出。由于一些系统问题,正在使用以下版本: JDK 1.8 英菲尼迪9.4.20 J组4.0.21 在我的示例中,我使用了一个简单的Java主场景,放置特定数量的数据,期望它们在特定时间段后过期。过期确实正在发生,因为