在 Java SSL 中处理密码更新
我有一个客户端-服务器 Java 应用程序,其中通信通过 SSL 进行。现在我正在手动生成密钥对,但我需要一个用于密钥管理的编程系统。
服务器维护一个用户数据库,而在客户端我不想存储密码的副本。客户端会以某种方式使用密码登录服务器。如果密码正确,服务器和客户端将建立密钥。从那时起,他们可以使用这些密钥而不必使用密码。这引出了我的第一个问题:
- 当用户第一次输入密码时,如何加密该传输?因为此时不会有密钥,因此也没有 SSL。
然后是用户更改密码的问题。这个想法是他们将通过网络界面更改服务器上的密码。然后,下次客户端连接时,他们的旧密钥应该不起作用,并且应该要求他们输入新密码。这引出了我的下一个问题:
- 什么是最佳实践 处理密码更改时 处理 SSL?
当他们更改密码时,我可以删除服务器端密钥。然后客户端将无法通信,然后我可以让客户端要求新密码。但这似乎有点笨拙。
I have a client-server java application, where communication happens over SSL. Right now I am generating keypairs by hand, but I need a programmatic system for key management.
The server maintains a user database, and on the client side I do not want to store a copy of the password. Somehow the client will log in to the server using a password. If the password is correct, the server and client will set up keys. From then on they can use those keys and not have to use the password. This brings me to my first question:
- When the user enters the password the first time, how do I encrypt that transmission? Because there will be no keys and thus no SSL at this point.
Then there is the issue of the user changing their password. The idea is they will go through a web interface to change their password on the server. Then the next time a client connects, their old keys should not work and they should be asked to enter the new password. Which brings me to my next question:
- What is the best practice for
handling the password change when
dealing with SSL?
I can just delete the server side key when they change their password. Then the client wont be able to communicate, and then I can have the client ask for a new password. But it seems a little kludgey.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
虽然 SSL 连接可以使用客户端证书对客户端进行身份验证,但它通常仅用于对服务器进行身份验证并在已识别的服务器之间创建加密连接(通过凭借与域名绑定的证书)和匿名客户端。
要使用客户端证书,客户端必须生成 PKCS 密钥对、证书签名请求,并由服务器信任的机构对其进行签名。如果没有该过程,客户端的身份验证通常是通过 SSL 之上的协议完成的,该协议需要一些只有客户端知道的秘密。这通常是一个密码,例如一个好的旧网站登录名。
相反,您所描述的实际上是机器生成的临时(凭空)密码(这些通常称为“密钥”,但是重要的是您要了解这实际上只是一个特殊的密码)。也就是说,在使用用户键入的密码对初始连接进行身份验证后,您向客户端发送一个临时密码以存储并用于后续连接。
要处理密码更改,您只需更改协议以允许临时密码。如果它不正确,但服务器有一个,您可能想要锁定帐户,假设有黑客尝试(尽管这可能是 DoS 攻击)。否则,如果由于服务器没有临时密钥而导致不正确(即服务器端因密码更改而将其清空),那么您只需向客户端发送响应以询问用户当前密码。然后,用户输入密码,假设密码匹配,服务器就会生成并传输新的临时密码。
编辑:澄清一下,即使您正在生成 PKCS 密钥对,但没有在客户端进行该操作并将它们绑定到证书中,这也不是客户端证书身份验证。它只是一个加密强度高的机器生成的临时密码。
并且请注意,最终,您的系统的强度仅与导致生成密钥对(或随后替换)的初始密码一样强。
While an SSL connection can authenticate the client using a client-side certificate, it's most often used only to authenticate the server and to create an encrypted connection between an identified server (by virtue of a certificate tied to a domain name), and an anonymous client.
To use client certificates the client must generate the PKCS key-pair, a certificate signing request and get it signed by an authority that the server trusts. Absent that process, authentication of the client is typically done be a protocol on top of SSL which requires some secret that only the client knows. This is typically a password, such as a good ol' website login.
Conversely, what you are describing is actually a machine generated ephemeral (out of thin air) password (these are often called "keys", but it's important that you understand it's really just a special password). That is, after an initial connection authenticated with a password typed by the user, you send the client an ephemeral password to store and use for subsequent connections.
To handle password change, you simply need to change your protocol to allow the ephemeral password. If it's not correct but the server has one, you might want to lock the account, assuming a hack attempt (though that can be a DoS opening). Otherwise, if it's not correct because the server has no ephemeral key (i.e. the server side has blanked it because the password was changed), then you simple send a response to the client to challenge the user for the current password. The user then enters the password, and assuming it matches, the server then generates and transmits a new ephemeral password.
EDIT: To clarify, even though your are generating PKCS key-pairs, without doing that client-side and binding them into a certificate, this is not client-side certificate authentication. It's merely a cryptographically strong machine generated ephemeral password.
And, beware, that at the end of the day, your system is only as strong as the initial password which caused the key-pair to be generated (or, subsequently, replaced).
您仍然可以在客户端和服务器之间使用 SSL。事实上,你应该这样做。
服务器还无法信任客户端。客户端可以信任服务器,因为服务器证书可供客户端使用。
例如,看看大多数 Web 登录是如何实现的:您尚未经过身份验证,但您将进入 HTTPS。这是单向 SSL。客户端正在使用临时密钥。密码通过加密连接传递。这可以防止窃听。
建立相互信任(通过验证密码)后,您可以通过同一连接传递客户端证书并重置会话。从那一刻起,您将拥有双向 SSL,即相互信任。
更新
由于“要求”的措辞不明确,我在线程中看到了一些混乱。让我写下客户端和服务器之间的协作:
会话 1:
会话 2:
You still can have SSL between client and server. In fact, you should.
The server won't be able to trust the client yet. Client can trust the server, because the server certificate is available to the client.
For example, look how most logins on web are implemented: you are not authenticated yet, but you're going into HTTPS. This is one-way SSL. Client is using a temporal key. Password is passed over the encrypted connection. This protects from eavesdropping.
When the mutual trust (through validation of the password) is established, you can pass client certificate over the same connection and reset the session. From that moment you'll have a two-way SSL, a mutual trust.
UPDATE
I see a bit of confusion in the thread due to not clear wording of "requirements". Let me write down the collaboration between client and server:
Session 1:
Session 2:
由于使用 SSL 进行客户端身份验证需要已共享密钥,因此您有两种选择:要么不使用 SSL 提供客户端身份验证,要么在将客户端证书交付给客户端后重新协商。
在第一个模型中,在第一次连接时,客户端首先在没有客户端身份验证的情况下通过 SSL 连接,然后发出某种登录命令,并接收会话令牌。此时,服务器知道该 SSL 连接上的另一方是该特定用户。如果客户端希望稍后重新连接,它只需在第二次连接开始时提供该会话令牌以对自己进行身份验证(仍然通过 SSL,但不使用客户端身份验证)。在此模型中,可以通过删除服务器的会话概念来撤销会话。
在第二种模型中,服务器通过提供其签名的客户端证书来响应登录命令。从那里,客户端将使用新证书重新协商连接。在此模型中,可以通过使用类似于证书吊销列表的内容来完成吊销(通过对证书使用适度的过期时间来防止列表变得太大)。
Since using SSL for client authentication requires keys to already be shared, you have two choices: either don't use SSL to provide client authentication, or renegotiate after delivering the client certificate to the client.
In the first model, on first connection, the client first connects over SSL with no client auth, then issues a login command of some sort, and receives a session token. At that point, the server knows that the other party on that SSL connection is that particular user. If the client wishes to reconnect later, it just present that session token to authenticate itself at the start of that second connection (still over SSL, but not using client auth). In this model, revocation of sessions can be done by deleting the server's notion of the session.
In the second model, the the server responds to the login command by providing a client cert that it signs. From there, the client will renegotiate the connection using the new certificate. In this model, revocation can be done by using something akin to a certificate revocation list (keep this from growing too big by using moderate expirations on the certificates).