使用Diffie-Hellman密钥交换和AES通过HTTP进行客户端加密

iRy*_*ell 11 javascript encryption aes node.js diffie-hellman

Diffie-Hellman Key Exchange上观看YouTube视频后,我想尝试用JavaScript实现(Atwood定律).

我使用以下规则在Node.js上绘制了一个密码:

  • 第1步:客户端和服务器就共享密钥达成一致:

    • 客户端和服务器以512位主公钥pK开头

    • 客户端生成512位主要私钥kC并发送powMod(3,kC,pK)

    • 服务器生成512位主要私钥kS并发送powMod(3,kS,pK)

    • 客户端和服务器使用powMod(响应,私钥,pK)作为共享密钥

  • 第2步:沟通

    • 在客户端发送数据之前,使用Stanford Javascript加密库(256位AES,HMAC身份验证,PBKDF2密码加密和CCM身份验证加密)使用共享密钥对其进行加密.

    • 一旦服务器使用共享密钥解密数据,它就会生成一个新的512位主要私钥,并将其作为SJCL加密响应发送.

    • 客户端和服务器使用powMod切换到新的共享密钥(3,prevSharedKey,newPrivKey)

现在我有几个问题..

与HTTPS或其他算法相比,这样的系统有多安全?这种系统最薄弱的地方是什么?

在安全性/实用性方面,使用1024位密钥以提高安全性会更好吗?HMAC/PBKDF2/CCM选项是否过度杀伤?是否值得调整共享密钥?谢谢阅读!

Jef*_*erg 17

你的系统非常不安全,但我并不是想劝阻你或任何人不要玩这样的东西.你应该继续.但至关重要的是,您认为您创造的任何东西都是一个"玩具"系统,永远不应被视为"安全".

让我们将安全问题分解为两部分.

  1. 密钥交换有多安全?
  2. 一旦获得共享密钥,您使用的加密有多安全?

让我先回答(2),因为这将是最简单的.除非你比那些多年来一直在研究和研究TLS的所有人更聪明,否则这将是非常不安全的.版本1.2之前的TLS(少数站点使用)在原则上容易受到选择的密文攻击(CCAs)的影响,并且在实践中容易受到BEAST攻击,这取决于密码套装的选择.SSL 2.0更加严重破坏.

重点是,非常聪明的人,多年来研究这些协议,有些不对劲.我有充分的理由相信你是我自己在做这些事情会犯很大的错误.基本的加密算法很好.他们没有被打破.但协议是.

因此,如果你没有研究并完全理解SSL的所有细节,为什么它们存在以及它们在某些情况下出了什么问题,那么几乎可以肯定,你设计的任何协议都会很糟糕.

现在回答问题(2).这有两个问题.(a)Diffie-Hellman并非旨在提供您可能需要的各种安全性; (b)我认为您没有正确实施DH.

2.A:

Diffie-Hellman密钥交换,当正确完成时,对于密钥交换是安全的,但它不会对身份验证做任何事情.这就是为什么"它是安全的"这个问题通常是错误的问题.它对于某些目的是安全的,但对于其他目的而言是非常不安全的,因为它不是为其他目的而设计的.

正如Josh3737指出的那样,客户端和服务器无法知道他们正在与合适的一方交谈.如果Sam是服务器而Charlie是客户端,那么没有什么可以阻止Mallory建立自己伪装成Sam的服务器.所以凯茜可以和马洛里进行密切交流,以为她正在和萨姆谈话.马洛里在与萨姆交谈时可以假装成查理.

一旦这样设置,马洛里就可以扮演萨姆和查理之间的中间人.当Charlie向Sam发送数据时,Mallory将使用C和M之间的共享密钥对其进行解密,读取它(并可能更改它),然后将M和S之间的共享密钥重新加密并将其发送给S .

要解决身份验证问题,您需要某种公钥基础结构(PKI),这些确实很痛苦.我们拥有SSL/TLS的证书颁发机构系统充满了问题,但它仍然是最好的系统.

2.B:

512位公共模数以及512位私钥不够强大.DH键需要更大.我不会选择低于2048位的东西.你可能会得到1024位,你并不担心有人能够在五年后打破今天的秘密.

您没有提供有关如何选择素数的足够信息.不是每个素数都会起作用.您需要为模数使用"安全素数",否则可以使用快捷方式让攻击者计算离散对数.


jos*_*736 8

我见过这样的问题面前 -这是完全不安全 的许多原因,其中最主要的是事实,这是不可能的JavaScript客户端验证服务器的密钥是真实的.

简而言之,如果没有SSL,您很容易受到中间人攻击.没有基于浏览器的JavaScript加密实现可以克服这个事实.

  • 这是一个非常无意义的答案,不应该被接受.源代码出处的问题与围绕在JS中编写DH的任何可能问题是正交的.这个答案是"中间解雇"的教科书示例:https://news.ycombinator.com/item?id = 4693920.Snarky足以获得投票,但在讨论中没有任何补充. (7认同)
  • 实际上,以可靠的方式将JS传递给客户端的唯一方法是通过SSL.既然您的连接已经安全,那么在那时做自己的加密有什么意义呢? (6认同)
  • 他从未说过他的作品是基于浏览器的.他特意说他是在node.js写的.即使他没有,它也可以用于其他许多地方和离线应用程序.忽略他的问题而只是告诉他这完全不安全是非常没有成效的. (5认同)