是否可以在c#asp.net站点的查询字符串中安全地包含密码。
我知道很少的假设和事情 -
我知道该网站可能容易受到跨网站脚本和重播攻击。我该如何减轻这些?
鉴于上述情况,我应该如何在查询字符串中包含密码?
请不要问我'为什么',我知道这不是一个好主意,但这是客户想要的。
答案 0 :(得分:5)
您可以使用SSL连接安全地将密码发送到Web服务器。这会加密客户端/服务器之间的所有通信。
基本身份验证协议将用户/密码信息放在HTTP请求标头中。 C#和许多其他Web服务器语言可以访问此信息,并使用它来验证请求。与SSL混合使用时非常安全。
如果以上都不可能,那么建议您为每个用户创建一个唯一的密钥。而不是发送他们的密码使用此密钥。优点是密钥存储在数据库中并可以删除。用户密码保持不变,但必须再次注册才能获得新密钥。如果有人可能滥用他们的密钥,那就好了。
握手是客户端向服务器发出请求的地方,服务器发回一个随机生成的密钥。然后,客户端使用密钥从该密钥生成哈希,并将其发送回服务器。然后,服务器可以检查客户端是否知道正确的密码。相反,密码是秘密,客户端在请求中包含用户名详细信息。这可以在不发送密码的情况下进行身份验证。
如果以上都不是可能的选项,那么您可以尝试使用JavaScript加密密码,然后再通过打开的URL发送密码。我找到了一个开源版本AES block cipher。该项目名为JSAES,支持128到256位加密。可能还有其他JS库可以做同样的事情。
答案 1 :(得分:0)
通常不建议将秘密放在查询字符串中,然后可以对其进行书签和复制,在历史文件,cookie等中公开密码。
要在此用例中保护密码,最好的选择是散列密码(单向,不可逆)。通过这种方式,实际密码在传输过程中也不知道,但是......它意味着攻击者仍然可以使用所述值登录到服务器,该服务器可能会将哈希值与其存储进行比较以进行身份验证。
用于在合理的时间段内记住用户会话的用例的更好解决方案是一个简单的用户会话令牌(Tomcat等所有应用程序服务器都使用它)。
在这种情况下,用户使用其密码(通过SSL)进行身份验证,但永远不会存储。密码在服务器上进行哈希处理,然后与用户帐户的密码哈希存储进行比较。如果哈希匹配,则对用户进行身份验证。
在身份验证时,服务器返回称为“会话ID”的限时nonce(令牌),然后将其存储并在浏览器cookie中重新发送。只要会话有效,用户就不再需要重新进行身份验证,并且永远不会存储密码。会话超时到期时,会话ID令牌不再有效,用户必须使用相同的进程重新进行身份验证。
双因素身份验证方案(请参阅Google身份验证器)和系统是一种更强大的安全状态(窃取密码不够,密钥在外部系统上自动轮换)但需要半频访问旋转密钥系统,这在一定程度上抑制了顺畅的用户体验。