我使用由SSL保护的Java NIO来连接客户端和服务器。要连接到服务器,系统会提示用户输入主机、端口、用户名和密码。到目前为止,我可以连接客户端和服务器(他们成功地完成了SSL握手),理论上我可以开始来回发送数据。我还没有编写一个验证登录凭据(用户名、密码)的机制。
服务器可以通过在数据库中查找用户名和密码来进行身份验证。如果客户端发送的凭据不正确,则连接将关闭。
问题1:何时验证凭据?我认为这必须发生在SSL握手之后。
问题2:如何在凭据被序列化并发送到服务器之前对其进行安全打包?我想我应该散列密码。我也应该散列用户名吗?
像这样简单的东西就够了吗?
public class LoginCredentials implements Serializable {
private static final long serialVersionUID = 1026410425432118798L;
private final String username;
private final byte[] passwordHash;
public LoginCredentials(String username, byte[] passwordHash) {
this.username = username;
this.passwordHash = passwordHash;
}
public final String getUsername() {
return username;
}
public final byte[] getPasswordHash() {
return passwordHash;
}
}
问题3:每个会话应该进行一次凭据身份验证,对吗?我读到一些帖子,似乎表明每个请求都应该验证凭据。
问题4:我应该使用哪种哈希算法?SHA–512似乎很受欢迎。
- 当然,在ssl握手之后,当建立ssl连接时,这会使其更加安全
- 没有多少应用程序真正做到这一点,它们中的大多数只是通过ssl发送密码,而不是对其进行哈希处理。是的,你可以生成一个哈希,但应该为每次登录生成哈希,所以它不会总是一样的,这需要客户端的一些代码来解决一些问题,包括正确的密码和服务器发送的一些随机的东西,否则它与常规的密码验证没有太大区别。但是有很多身份验证机制——密码、哈希、令牌、ssl证书等等
- 您需要检查经过身份验证的用户是否有权访问他试图访问的资源——这是针对每个请求的,而不是针对每个请求登录用户(如果您有会话)。如果你需要管理用户访问权限以在单个会话期间授予或撤销访问权限,那么你需要读取每个请求的用户访问权限,如果你不需要这样的粒度,那么在整个会话中读取一次就可以了。有时有无会话服务,例如一些REST,那么通常你需要在每次调用时发送一些凭据
- 你可以使用任何不太容易破译的哈希算法