在您的问题中,您链接到一篇解释(经典/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 仅支持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)
.