【问题标题】:How to safely include password in query string如何在查询字符串中安全地包含密码
【发布时间】:2013-01-02 19:30:51
【问题描述】:

是否可以在 c# asp.net 站点的查询字符串中安全地包含密码。

我知道的一些假设和事情 -

  1. 该网站没有也不会有与其他网站的链接/图像/javascript/分析。因此,无需担心引荐链接。
  2. 与网络浏览器的所有通信都将通过 https。
  3. 我知道查询字符串将保留在 电脑。
  4. 不仅需要密码/用户名登录。如此简单 将网址粘贴回浏览器不会导致登录。

我知道该站点可能容易受到跨站点脚本和重放攻击。我该如何减轻这些?

鉴于上述情况,我应该如何在查询字符串中包含密码?

请不要问我“为什么”,我知道这不是一个好主意,但这是客户想要的。

【问题讨论】:

  • 你为什么要这样做?
  • 如果密码的有效期有限,您可能会减轻一些负面影响
  • 如果你真的必须这样做,你可以用一个密钥来加密它。这样你就有了某种安全感
  • 从黑客的角度来看,加密不会有任何区别,他们只需要 URL 历史记录就可以破解
  • @tom:好的,这意味着服务器是基于会话的?这反过来意味着查询字符串中不需要密码。请原谅我绕着圈子兜圈子,但这些要求并没有真正的意义,所以很难想出有意义的回应......

标签: c# asp.net encryption passwords query-string


【解决方案1】:

SSL

您可以使用 SSL 连接安全地将密码发送到 Web 服务器。这会加密客户端/服务器之间的所有通信。

隐藏在标题中

基本身份验证协议将用户/密码信息放在 HTTP 请求标头中。 C# 和许多其他 Web 服务器语言可以访问此信息,并使用它来验证请求。与 SSL 混合使用时非常安全。

注册应用程序密钥

如果以上都不可行,那么建议您为每个用户创建一个唯一的密钥。而不是发送他们的密码,这个密钥被使用。优点是密钥存储在数据库中,可以删除。用户的密码保持不变,但他们必须重新注册才能获得新密钥。如果有人可能滥用他们的密钥,这很好。

进行握手

握手是客户端向服务器发出请求,服务器发回随机生成的密钥。然后,客户端使用密钥从该密钥生成哈希,并将其发送回服务器。然后服务器可以检查客户端是否知道正确的秘密。如果密码是秘密并且客户端在请求中包含用户名详细信息,则可以执行相同的操作。这可以在不发送密码的情况下进行身份验证。

加密密码

如果以上都不是可能的选项,那么您可以尝试在密码通过开放 URL 发送之前使用 JavaScript 对其进行加密。我找到了一个开源版本AES block cipher。该项目名为JSAES,支持 128 到 256 位加密。可能还有其他 JS 库做同样的事情。

【讨论】:

  • OP 询问如何安全地将 PW 包含在查询字符串中...加密密码需要一个新的秘密(密码已经是),它将问题循环回到自身(密钥将如何保护并传输以解密密码)?
  • @ThinkingMedia https (SSL/TLS) 加密查询字符串。只有 URL 地址是明文的。
  • 使用公钥对密码进行哈希处理并发送到服务器,使用私钥生成数据库中匹配的密码列的密钥。在此过程中不使用实际的密码文本,您可以即时生成公钥,以便哈希值不断变化。这基本上是一种发送 MD5(my_password) 的更复杂的方式。因为任何人都可以使用 MD5 作为指南来找出原始密码。加密只是使将哈希值反转回原始密码变得非常困难。
  • 当您使用 MD5(password) 时,它会为每个密码生成相同的哈希值,但每次加密都会为相同的密码生成不同的哈希值。这就是为什么服务器需要使用私钥来生成与该密码一致的哈希。
  • 虽然不推荐整体答案,但@Reactgular 不得不说的有优点(使用 PKI)......除了生成新的公钥/私钥对非常昂贵和复杂,所以不会这样做那。对于一般加密情况,使用混合加密(有效负载的随机对称密钥,已知目标的加密密钥 RSA)我的答案是日耳曼:stackoverflow.com/questions/44391/…
【解决方案2】:

通常不建议将秘密放入查询字符串中,然后可以将其标记和复制,从而将静态密码暴露在历史文件、cookie 等中。

只是在这个用例中保护密码,一个选项是散列密码(单向,不可逆)。通过这种方式,实际密码在传输过程中或静止时都是未知的,但是......这意味着攻击者仍然可以使用散列值登录到可能会比较散列值的服务器到其商店进行身份验证。

更新:切换到无状态 (JWT) 会话

在过去,马车是一回事(好吧 - 它们仍然是一些边缘群体的东西,但是) - 我们使用“会话”。 例如,在基于 Java/J2EE/Servlet 的系统中,“会话 ID”(参见 JSESSION_ID)被存储为 cookie。该值是一个随机数,很难猜测 - 但它存在劫持到内存和服务器上查找开销的问题。

在 2020 年(截至撰写本文时)... JSON Web 令牌 (JWT) 可用于安全地封装用户会话信息,并在不暴露密码的情况下将其推送回不可变 cookie,而且只需很少服务器开销。

在此模型中,登录后,服务器会发出一个令牌(使用 OAUTH2 或相关),该令牌具有过期时间戳。

然后可以对这些数据和可能的其他会话信息进行加密、散列、签名和包装在 JWT(令牌)中 - 作为 cookie 返回到网络浏览器。

参考:https://oauth.net/2/jwt/

此时,客户端不能做任何事情来破坏(甚至查看)cookie,因为任何敏感数据都应该被加密(使用 AES256 等或更好的)并且内容被散列和散列签名。这意味着当服务器取回令牌时,它会查看时间戳并可能将其丢弃 - 强制重新身份验证,然后......

可以以其他方式验证它对内容进行签名、对内容进行哈希处理并验证哈希值并在需要时解密数据(其中不包括密码,而只是用户的 ID - 已验证且本身不一定是秘密) .

这可以包括用户可以执行的操作的已查找范围(授权)等 - 在令牌超时之前避免往返身份验证服务器。

因此,上述方法(使用 JWT、散列、签名、加密 - 到 cookie 中)是实现无状态并避免在客户端和服务器之间传递秘密的推荐方法。

参考:https://auth0.com/blog/stateless-auth-for-stateful-minds/

此外,考虑到多因素身份验证方案(请参阅 Google 身份验证器)和相关系统的安全性要强得多(窃取密码是不够的,并且密钥会在外部系统上自动轮换),但确实需要半频繁地访问旋转按键系统,在一定程度上抑制了流畅的用户体验。

更新:Google 和其他公司的 Multi-Factor auth 已经变得更好了。

较老的公司仍然使用 SMS 一次性密码 (OTP) ... 去无线公司商店并声称 SIM 卡丢失(给定一个已知的电话号码)可能会受到影响。 谷歌和其他更先进的公司相对使用可嵌入智能手机应用程序中的旋转令牌,然后用于许多服务。 谷歌甚至有推送通知,用户只需按下按钮确认:“是的 - 是我”。

【讨论】:

    猜你喜欢
    • 2020-12-16
    • 1970-01-01
    • 2022-11-11
    • 1970-01-01
    • 1970-01-01
    • 2011-02-19
    • 1970-01-01
    • 2011-05-14
    • 1970-01-01
    相关资源
    最近更新 更多