我们计划使用ECDHE算法在客户端和服务器之间交换密钥,以使两者都可以导出公用密钥来加密邮件
根据我所读的内容,要使用ECDHE算法,双方(客户端和服务器)都应首先就一对“公共”值(p,g)达成一致。然后,各方将使用私钥生成共享密钥,即客户端使用私钥(P1)生成共享密钥(S1),服务器使用私钥(P2)生成共享密钥(S2) 参考:[https://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange#Description]
此处的常用值是指常用涂料。这些实际上是双方用来生成共享密钥的mod值(p)和基值(g)。
然后双方交换共享密钥(S1和S2),并将其与自己的私有密钥(P1或P2)一起使用,以得出公共秘密(K)
当我查看使用ECDiffieHellmanCng生成键的样本时,看不到在任何地方指定这些“公共”值的选项。在我们的例子中,我期望客户端和服务器都同意p和g,然后将这些值与“ ECDiffieHellmanCng”一起使用以生成公共共享密钥。
我看到Alice和Bob创建了ECDiffieHellmanCng的新实例-他们内部是否都使用相同的通用值(p和g)?
答案 0 :(得分:0)
是的,他们必须在Field Fq上使用相同的基点和相同的椭圆曲线E。这些是公开的。
答案 1 :(得分:0)
在您的问题中,您链接到说明(经典/ IFC)Diffie-Hellman的文章,secret = (g ^^ (alice * bob)) % p
。然后,您提到ECDHE,并询问.NET中的ECDiffieHellman(Cng)类,该类是关于椭圆曲线Diffie-Hellman ... IFC(整数分解密码)算法的ECC变体。
(IFC)DH肯定有一个选择一个好的(g, p)
组合的引导问题,并且不会被中间的一个人欺骗。对于TLS,连接的服务器端可以组成所需的任何(g, p)
,然后告诉客户端它选择了什么,但是客户端无法真正知道它是否被欺骗。如果双方都拥有,则可以通过在2048位空间中生成一个质量组并坚持下去来解决此问题。
.NET内置的(IFC)Diffie-Hellman不支持。
ECDH具有一组不同的参数,这些参数统称为“曲线”。对于素数曲线(最常见的形式),参数是元组(p, a, b, G, n, h)
(尽管实际上n
和h
是来自(p, a, b, G)
的计算),然后是{{3} }。定义ECC数学后,ECDH为secret = X-Coordinate((alice * bob) * G)
。 ECC具有与(IFC)DH相同的陷阱,为参数选择错误的值可以让对方玩把戏。由于存在潜在的欺骗性,并且域参数很大,因此将域参数的选择标准化为“命名曲线”。根据定义,同一条曲线上的两个关键点具有相同的域参数集。在TLS中,仅允许使用曲线的名称(以及对象标识符值)。服务器几乎可以选择什么参数集,但是为了获得最大的互操作性,通常只有(截至2018年)从以下三个曲线中选择:secp256r1
(又名NIST P-256),secp384r1
(又名NIST) P-384)和secp521r1
(又名NIST P-521)。
ECDiffieHellmanCng默认使用secp521r1
,但是您可以通过三种不同方式之一控制曲线:
更改KeySize值(将其设置为除当前值以外的任何值)会导致在该大小的曲线上生成关键点。这对于Windows 7、8和8.1完全有意义,因为Windows CNG仅支持secp256r1
,secp384r1
和secp521r1
。因此,您可以将KeySize设置为{256,384,521}中的任何一个。
using (ECDiffieHellman ecdh = ECDiffieHellman.Create())
{
ecdh.KeySize = 384;
...
}
Windows 10添加了对更多曲线的支持,并且大小变得模棱两可。 256是否表示secp256r1
或brainpoolp256r1
(或brainpoolp256t1
,numsp256t1
,secp256k1
,...)?好的,这意味着secp256r1
,并且存在更复杂的API。
ECDiffieHellman.Create
工厂有一个重载(.NET Core 2.1 + ,. NET Framework 4.7+),它可以接受ECCurve
。因此,在secp384r1
上创建曲线的另一种方法是
using (ECDiffieHellman ecdh = ECDiffieHellman.Create(ECCurve.NamedCurves.nistP384))
{
...
}
也许您正在使用DI,但不能很好地使用工厂。好吧,您可以使用GenerateKey
方法(.NET Core 2.1 + 、. NET Framework 4.7+)获得相同的结果
using (ECDiffieHellman ecdh = ECDiffieHellman.Create())
{
ecdh.GenerateKey(ECCurve.NamedCurves.nistP384);
...
}
还有其他获取ECCurve值的方法,例如ECCurve.CreateFromValue("1.3.132.0.34")
或仅从(p, a, b, G = (Gx, Gy), n, h)
手动构建它。