首页 > 解决方案 > 如何在客户端安全地保护服务器身份验证密码?

问题描述

在我的应用程序中,客户端通过SSLSocket. 为了进行身份验证,服务器发送盐,客户端发送使用给定盐加密的密码。

我实际上不想让用户每次都输入他的密码,但另一方面我不想遇到安全问题。

我阅读了有关密钥库的信息,但它们安全吗?而且据我了解,用户仍然需要输入密码。

什么是安全且用户舒适的解决方案?

标签: javasecuritypasswordskeystore

解决方案


如果我理解正确,您当前的协议如下所示:

server -> client: random nonce
server <- client: encrypted password
server <- client: encrypted password

客户不必一次又一次地发送他的密码,我建议您在协议中利用访问令牌。访问令牌(“身份验证令牌”、“会话 ID”)是一个很大的随机值,服务器将其作为身份验证响应返回:

server <- client: encrypted password
server -> client: 256-bit access token
server <- client: 256-bit access token
server <- client: 256-bit access token

这是一个会话管理。NIST 提供有关会话管理的建议:https ://pages.nist.gov/800-63-3/sp800-63b.html#sec7

会话管理优于凭证的持续呈现,因为持续呈现的较差可用性通常会激励诸如缓存解锁凭证之类的变通方法,从而否定身份验证事件的新鲜度。

客户端将访问令牌保存在内存中并使用它而不是密码。如果要在应用程序启动之间保留访问令牌,则必须安全地存储它,这取决于客户端的操作系统:

  1. 安卓:密钥库。
  2. iOS:钥匙串。
  3. Linux/Windows/MacOS:这里很难——只要将令牌尽可能长时间地保存在内存中,不要放入文件中,让应用程序尽可能长时间地运行。

无论哪种方式,访问令牌都必须在一段时间后过期,即使它由于某种原因泄露,客户端也会在一段时间后得到一个新的。请参阅 NIST 中有关重新认证的部分。


推荐阅读