使用ECDiffieHellmanCng交换密钥

时间:2018-10-22 12:40:29

标签: c# .net cryptography ecdhe

我们计划使用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”一起使用以生成公共共享密钥。

参考:https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.ecdiffiehellmancng?view=netframework-4.7.2

我看到Alice和Bob创建了ECDiffieHellmanCng的新实例-他们内部是否都使用相同的通用值(p和g)?

2 个答案:

答案 0 :(得分:0)

  • GF(q)表示具有q个元素的有限域
  • p是基点

是的,他们必须在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)(尽管实际上nh是来自(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,但是您可以通过三种不同方式之一控制曲线:

设置ecdh.KeySize

更改KeySize值(将其设置为除当前值以外的任何值)会导致在该大小的曲线上生成关键点。这对于Windows 7、8和8.1完全有意义,因为Windows CNG仅支持secp256r1secp384r1secp521r1。因此,您可以将KeySize设置为{256,384,521}中的任何一个。

using (ECDiffieHellman ecdh = ECDiffieHellman.Create())
{
    ecdh.KeySize = 384;
    ...
}

那样创建

Windows 10添加了对更多曲线的支持,并且大小变得模棱两可。 256是否表示secp256r1brainpoolp256r1(或brainpoolp256t1numsp256t1secp256k1,...)?好的,这意味着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)手动构建它。

相关问题