代码之家  ›  专栏  ›  技术社区  ›  loneboat

通过HTTP(而不是HTTPS)验证用户

  •  5
  • loneboat  · 技术社区  · 14 年前

    初步说明:这只是一个个人修补项目;我不是在这里编写企业安全性,如果是的话,我知道最好不要尝试编写自己的方案。:-D个

    编辑: 为了强调上述观点,我尝试将其标记为“Iknow this wouldbadeainrealllife”,但不接受,因为它是>25个字符。请注意,我知道这不是商业级的!

    我需要一种通过HTTP对用户进行身份验证的方法(在这种情况下不能使用HTTPS)。我需要知道另一端的人真的是他们所说的那个人(在相当高的程度上)。一旦我确定用户是合法的,我 不在乎

    (假设 A' 分别表示私钥和公钥;并且, enc(文本,键) dec(密码文本,键)

        +------------------------+------------------------------+
        |         SERVER         |            CLIENT            |
        +------------------------+------------------------------+
    (1) | t = randomToken()      |                              |
    (2) | enc(t, A)           -------->  c                      |
    (3) |                        |       A' = getKeyFromUser()  |
    (4) | p                 <--------    p=dec(c, A')           |
    (5) | if (t==p)              |                              |
        |     allowAccess()      |                              |
        | else                   |                              |
        |     denyAccess()       |                              |
        +------------------------+------------------------------+
    

    我在这里看到的一个弱点是,听交换的坏人,而他没有 A ,现在有一个已知的密文/明文组合,我记得加密类是 . 我想加点盐可以缓解这种情况?

    下面是我的两个问题:

    1. 克服上述“已知明文/密码对”弱点的最佳方法是什么?加盐?

    谢谢!


    谢谢大家的讨论!只是想澄清一下:

    • 我并不担心向客户保证服务器就是他们所说的那样。只有相反的情况(向服务器保证客户机就是他们所说的那样)
    • 我知道MITM的袭击。这项计划并不是为了保护他们。
    • 我知道已经有很多解决办法了。这对我来说纯粹是一个学习练习!我不是想重新发明轮子或者制造更好的捕鼠器。这只是为了好玩!
    • 下面是我对这个方案的思考过程:(我知道我并没有很好地使用公钥和私钥,但请耐心听我说)

      • 鲍勃走向爱丽丝说:“嘿,我是鲍勃。”

      • 爱丽丝说:“好吧。我知道鲍勃的私钥。如果你真的是鲍勃,请把这个我刚刚加密的秘密消息(用鲍勃的私钥)拿出来,帮我解密。”

      • 鲍勃回复了正确的信息,爱丽丝很高兴。

    6 回复  |  直到 14 年前
        1
  •  1
  •   Aillyn    14 年前

    基本上,您希望在HTTP上实现SSL;这在某种程度上是可行的,但永远不会像实际情况那样好。

    能够来回发送加密数据只是问题的一半。问题的另一部分是确保您实际上是在与服务器交谈(想想中间人攻击)。

    1. 服务器向客户端发送随机令牌。服务器将令牌存储在“挂起”列表中。可以每隔一段时间(例如:每15分钟)清洗一次
    2. 客户端发送 enc(comb(username, password, token), pubKey) 回到服务器,在哪里 comb()
    3. 服务器使用 decomb(dec(message, privKey)) decomb() 是的倒数 .

    如果生成的令牌从不重复,攻击者就不能仅仅重新发送相同的加密消息,也不能解密消息以找出所有内容。

        2
  •  3
  •   Bruno    14 年前

    你可以用 HTTP Digest Authentication . 大多数浏览器、服务器和各种库都已经支持这一点。

    编辑:

    如果您真的想使用一些没有SSL/TLS的公钥加密,您可以看看 HTTPsec

    如果你真的想发明你自己的身份验证方案,你应该注意到你的标签的加密/解密是错误的(不确定这是否是一个打字错误,或者我没有正确地阅读图表,这看起来像是你在做的) 环境温度(t,A) 在服务器端):

    • 你用私钥解密
    • 使用公钥验证签名

        3
  •  2
  •   erickson    14 年前

    如果将RSA与适当的填充机制(如OAEP)结合使用,它就不易受到已知的明文攻击。所以没必要回避这个问题。

    一个陌生人走了过来,声称自己是鲍勃。为了证明这一点,他们证明他们知道一个只有真正的鲍勃知道的秘密。在公钥密码学中,秘密是 钥匙。

    在您的方案中,首先必须获取Bob的公钥,并确保它确实是Bob的,以便稍后可以使用它来加密挑战。如何引导这个过程?

    现在“Bob”正确地响应了您的挑战,并为他的请求添加了一些说明。你怎么知道中间的那个女人,伊芙,没有砍掉鲍勃真正的指令,而代之以她自己的指令?

    如果你真的要这么做,你应该想办法 数字签名

        4
  •  1
  •   Darron    14 年前

    假设您的客户机和服务器在此交换开始之前交换了一个公钥,您可以执行以下操作:

    1. 客户端发送HTTP请求,请求头包含用户名和加密(私钥,user+URL)
    2. 服务器尝试使用指定用户的公钥解密头的内容。
    3. 如果解密失败,或者所包含的用户或URL不匹配,请求将被拒绝。

    包含URL是为了防止针对不同资源的重播攻击。通过在加密数据中包含时间戳,可以获得更高的防止重播的安全性。

    编辑:删除提及AES128。

        5
  •  0
  •   Vass    14 年前

    正如Bruno所说,您描述的是HTTP摘要,它非常安全。但如果你仔细看的话,就会发现环洞。不是很大。一定要有人在听,等着拿起握手中的钥匙,才能破门而入。如果安全是一个问题,你必须使用https和让路给它。这就是为什么它在那里。https有证书可以使握手在一开始就抵抗窃听者。

        6
  •  0
  •   rook    14 年前

    首先,HTTPS做的不仅仅是加密。它还可以防止活动的MTIM攻击并保护您的会话id。如果您只是泄漏会话id,则密码没有意义。这是OWASP A9的一部分。

    JavaScript solution . 对会话id和密码进行加密。它使用Diffie-Hellman密钥交换,类似SSL。就连作者也说,它不是https的好替代品,但总比什么都没有好。我甚至不会考虑使用https以外的任何东西。