0

我们计划使用 ECDHE 算法在客户端和服务器之间交换密钥,以便双方都可以导出一个公共密钥来加密消息

根据我所阅读的内容,要使用 ECDHE 算法,双方(客户端和服务器)应该首先就一对“公共”值(p,g)达成一致。然后每一方将使用私钥生成共享密钥,即客户端使用私钥(P1)生成共享密钥(S1),服务器使用私钥(P2)生成共享密钥(S2)参考:[ https://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange#Description]

这里的共同价值是指共同的油漆。这些实际上是双方用来生成共享密钥的模值(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)?

4

2 回答 2

4

在您的问题中,您链接到一篇解释(经典/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之上定义 ECC 数学。一旦定义了 ECC 数学,ECDH 就是h(p, a, b, G)secret = X-Coordinate((alice * bob) * G). ECC 与 (IFC)DH 有相同的陷阱,为参数选择错误的值可以让对方玩诡计。由于潜在的诡计,以及域参数很大的事实,域参数的选择被标准化为“命名曲线”。根据定义,同一曲线上的两个键具有相同的域参数集。在 TLS 中,您只能使用曲线的名称(嗯,对象标识符值)。服务器几乎可以选择哪组参数,但为了获得最大的互操作性,通常只选择三个曲线(截至 2018 年):(secp256r1又名 NIST P-256)、secp384r1(又名 NIST P-384)和secp521r1(又名 NIST P -521)。

ECDiffieHellmanCng 默认为 using 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(或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).

于 2018-10-26T15:52:45.237 回答
0
  • GF(q) 表示具有 q 个元素的有限域
  • p 是一个基点

是的,他们必须在场 Fq 上使用相同的基点和相同的椭圆曲线 E。这些是公开的。

于 2018-10-22T18:51:51.320 回答