Java 如何在Spring中减少攻击内存中密码的表面积?

Java 如何在Spring中减少攻击内存中密码的表面积?,java,spring,security,spring-security,jackson,Java,Spring,Security,Spring Security,Jackson,Strings在Java中可能会保留一段时间。这是一件好事,除非字符串包含用户的实际密码。因为它们不是一成不变的,可以更快地清除。(我们希望永远不会有像Heartbleed那样针对JVM(远程堆转储)的“苦咖啡”攻击) 我注意到Spring Security PasswordEncoder采用的是CharSequence而不是字符串,可能是出于这个原因。但是,我不确定应该使用什么对象在哈希前将密码保存在内存中。StringBuilder是否合适?那会是什么样子?如果我正在创建一个RESTAPI(

String
s在Java中可能会保留一段时间。这是一件好事,除非
字符串
包含用户的实际密码。因为它们不是一成不变的,可以更快地清除。(我们希望永远不会有像Heartbleed那样针对JVM(远程堆转储)的“苦咖啡”攻击)

我注意到Spring Security PasswordEncoder采用的是
CharSequence
而不是字符串,可能是出于这个原因。但是,我不确定应该使用什么对象在哈希前将密码保存在内存中。
StringBuilder
是否合适?那会是什么样子?如果我正在创建一个RESTAPI(Jackson在幕后,通过Spring数据或Spring MVC),我甚至不太确定如何才能避免它成为一个
字符串

如何编写JSON REST API来创建/更新密码,同时尽可能安全并避免使用
String
s时出现的各种问题

如何编写JSON REST API来创建/更新密码 尽可能安全,避免各种问题 使用字符串

API密钥不是真正的密码。您可以控制如何创建API键,以便创建一些随机字符串,这些字符串将具有非常低的冲突(即双UUID)和非常低的公共子字符串(在重复数据消除的情况下)。在客户端使用密钥通过RESTAPI登录之后,您可以使用临时令牌,从而提高API密钥被垃圾收集的可能性

至于处理真正的密码(可能是为了重置API密钥),由于几乎每个servlet容器都会将请求参数转换为字符串,因此您实际上没有太多选择。一个很简单的选择是让客户端通过Javascript(或任何客户端)Base64对密码进行编码,然后添加分隔符,然后向密码中添加随机生成的数字或字符串。这并不是为了混淆,而是为了降低保留相同字符串的概率。当然,在解码成char或byte数组时必须小心,然后通过操作char或byte数组来删除随机后缀(请参见CharBuffer)

另一个复杂的选择是微服务云方法。只需创建一个由几个只执行身份验证的小循环实例组成的身份验证服务。让那些JVM实例频繁重启(以刷新内存)。或者,如果它们足够小,它们将有望更频繁地收集垃圾

当然,我会假设您的数据存储库中有附加密码(否则,这种安全预防措施就毫无意义了)

老实说,尽管还有很多其他威胁,我真的认为在HTTP服务器环境中的大多数用例中不值得这么做

Java Swing之所以使用
char[]
作为密码,是因为Swing用于桌面环境。桌面环境更可能有恶意程序,如病毒/间谍软件,它们可以对密码进行一些内存探测


考虑到这一点,您真正应该担心的是客户端,而不是服务器。

在使用spring security之前,您必须避免大多数REST框架(包括spring security内置的web security)将密码作为请求参数检索。。。这是一个字符串。是的,我正在构建的API主要是以angular或其他方式编写的后台和用户前端,我的实体目前正在通过BCryptPasswordEncoder进行转换。我有点喜欢你关于什么是有效的客户端盐的想法。可以使用csrfToken进行验证。我们希望永远不会发生远程内存攻击,但我担心“Java Debugger over HTTP”+“字符串重复数据消除”等功能更可能导致这种情况。也可以考虑一下,我们可以在不太可能的情况下建立特征,也可以记住java不是C++或者C++,也没有无效的指针运算,缓冲区溢出等等。因此,虽然在内存中挂着密码仍然有点不好,但与其他没有保护内存分配的语言相比,它并没有那么糟糕。对,“我的代码”永远不会导致问题。但是Java有热点,是用C写的吗?哪个有那个。。。我并不是说这会发生,只是在想万一发生什么,最坏的情况。就像让别人心碎的错误。。。一个语言错误。。。或(您使用password123在prod上通过http打开调试器是什么意思)。我最初还认为这可能只是一个知识/文档的缺口。是的,但它也在一个服务器上,我希望它能被一个相当稳定的JVM锁定。实际上,你需要担心的是你的客户会泄露密码(例如钓鱼)。你不想花很多时间在错误的地方建造一堵巨大的墙。