Java 应用程序级安全远程密码协议

Java 应用程序级安全远程密码协议,java,jakarta-ee,security,srp-protocol,Java,Jakarta Ee,Security,Srp Protocol,我正在编写一个JavaEE应用程序,它允许新用户注册自己,然后通过Internet登录。我正在将凭据存储到数据库中 现在,有几种方法可以做到这一点,例如: 发送用户名和密码,最好通过TLS/SSL连接 发送用户名和密码的哈希代码,最好通过TLS/SSL连接 使用安全远程密码协议(最好通过TLS/SSL连接?) 阅读一些文章,似乎安全远程密码协议(SRP)是一条出路 但在阅读其他一些文章时,这似乎只在一些低级层上使用,例如TLS/SSL本身 我仍然认为,建议在应用程序级别使用安全的远程密码协议

我正在编写一个JavaEE应用程序,它允许新用户注册自己,然后通过Internet登录。我正在将凭据存储到数据库中

现在,有几种方法可以做到这一点,例如:

  • 发送用户名和密码,最好通过TLS/SSL连接
  • 发送用户名和密码的哈希代码,最好通过TLS/SSL连接
  • 使用安全远程密码协议(最好通过TLS/SSL连接?)
阅读一些文章,似乎安全远程密码协议(SRP)是一条出路

但在阅读其他一些文章时,这似乎只在一些低级层上使用,例如TLS/SSL本身

我仍然认为,建议在应用程序级别使用安全的远程密码协议


这是正确的吗?还是有一些很好的理由说明为什么在应用程序级别上不需要这样做?

有一些权衡要考虑。首先,当且仅当客户机正确验证服务器的SSL证书时,通过SSL链路发送原始密码是相当安全的。但是,即使执行了正确的SSL证书验证,将原始密码发送到服务器也不完全理想。被黑客攻击的服务器可能会暴露用户的密码。由于密码经常在其他地方重复使用,这种暴露具有潜在的严重影响

SRP的一个优点是它避免了这两个问题。用户的密码永远不会离开他们的机器,并且不需要正确的SSL证书验证。SRP的相互身份验证属性使SSL证书变得冗余。事实上,一些应用程序利用这一点完全避免了与正确的SSL证书管理相关的头痛问题。他们只是在服务器上使用匿名、自签名证书,仅用于数据加密目的,并将身份验证留给应用程序级SRP


具体到您的问题,我认为SRP对低级和应用程序级使用的适用性实际上取决于您的应用程序。它在这两个领域都能很好地发挥作用,但它的最佳应用实际上可以归结为您正在处理的一组特定的设计约束。

人们应该在TLS/SSL上使用SRP,因为它们是互补的

如果您的用户通过网络注册或重置其SRP密码验证器,则需要加密连接;因为验证器应该保密,这样它就不会受到离线暴力攻击。TLS/SSL/HTTPS非常适合于此。它们建立良好,对所有数据进行加密,并提供服务器证书的保护,以确保浏览器不会与欺骗服务器通信

SRP意味着您的用户通过身份验证的密码不会跨网络。如果您的用户通过公司web代理使用公司提供的计算机,则可能需要HTTPS。Hearbleed bug还表明,配置良好的HTTPS可能存在问题。笔记本电脑制造商故意在其销售的笔记本电脑上泄露HTTPS,以便在加密页面中插入广告。可能存在泄露的根证书,用于窥探员工。即使有完美的加密设置,应用程序也可能意外地将密码泄漏到日志中;而SRP使用随机输入进行一次性密码验证。因此,SRP保护密码不会离开客户机,这比让密码进入两台机器上的内存(可能会泄露)更安全


结果是人们应该同时使用SRP和HTTPS/TLS/SSL

通过SSL发送原始密码足够安全。当然,服务器端的密码需要进行散列和盐渍处理。但是对散列密码不存在可能的攻击吗?例如,当某人设法获取用户名和密码哈希列表时(最近发生在LinedIn上)。SecureSafe似乎也出于某种原因使用SRP协议。。。()是的,可以对哈希密码实施暴力攻击。在这方面,SRP并不比散列密码更安全,因为服务器端密钥同样容易受到这种形式的攻击。ThinbusSRP有一个使用SRP登录JEE Spring MVC应用程序和另一个仅使用rest应用程序的演示。因此,SRP对于服务器端攻击具有优势,因为密码永远不会与服务器共享,但是对于客户端的钓鱼攻击呢?当客户在输入密码时按键被监控时,SRP难道不会同样容易受到攻击吗?是的。它根本不提供防止客户端窥探的保护。