简体   繁体   English

使用ECDiffieHellmanCng交换密钥

[英]Using ECDiffieHellmanCng to exchange keys

We plan to use ECDHE algorithm to exchange keys between client and server so that both can derive a common secret key to encrypt messages 我们计划使用ECDHE算法在客户端和服务器之间交换密钥,以便两者都可以导出公用密钥来对消息进行加密

Based on what I have read, to use ECDHE algorithm both parties (client and server) should agree on a pair of "common" values (p, g) first. 根据我所读的内容,要使用ECDHE算法,双方(客户端和服务器)都应该首先在一对“公共”值(p,g)上达成一致。 Then each party will use a private key to generate a shared key ie client uses a private key (P1) to generate a shared key (S1) and server uses a private key (P2) to generate a shared key (S2) Ref: [ https://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange#Description] 然后,各方将使用私钥生成共享密钥,即客户端使用私钥(P1)生成共享密钥(S1),而服务器使用私钥(P2)生成共享密钥(S2)参考:[ https://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange#Description]

Common value here refers to the common paint. 这里的共同价值是指共同的油漆。 These are actually the mod value (p) and base value (g) used by both parties to generate the shared keys. 这些实际上是双方用来生成共享密钥的mod值(p)和基值(g)。

Both parties then exchange the shared keys (S1 and S2) and use it with their own private key (P1 or P2) to derive the common secret (K) 然后,双方交换共享密钥(S1和S2),并将其与自己的私有密钥(P1或P2)一起使用以得出公共秘密(K)

When I look at samples that use ECDiffieHellmanCng to generate keys, I do not see an option to specify these "common" values anywhere. 当我查看使用ECDiffieHellmanCng生成键的样本时,看不到在任何地方指定这些“公共”值的选项。 In our case, I was expecting both client and server to agree on p and g and then use those values with "ECDiffieHellmanCng" to generate the common shared key. 在我们的例子中,我期望客户端和服务器都同意p和g,然后将这些值与“ ECDiffieHellmanCng”一起使用以生成公共共享密钥。

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

I see Alice and Bob create new instance of ECDiffieHellmanCng - do they both internally use the same common values (p and g)? 我看到Alice和Bob创建了ECDiffieHellmanCng的新实例-它们在内部都使用相同的公共值(p和g)吗?

  • GF(q) denote the finite field with q elements GF(q)表示带有q个元素的有限域
  • p is a base point p是一个基点

Yes, they must use same basepoint and same Elliptic Curve E over a Field Fq. 是的,他们必须在Field Fq上使用相同的基点和相同的椭圆曲线E。 these are public. 这些是公开的。

In your question you link to an article explaining (classic/IFC) Diffie-Hellman, which is secret = (g ^^ (alice * bob)) % p . 在您的问题中,您链接到解释(经典/ IFC)Diffie-Hellman的文章,这是secret = (g ^^ (alice * bob)) % p You then mention ECDHE and ask about the ECDiffieHellman(Cng) class in .NET, which is about Elliptic Curve Diffie-Hellman... the ECC variant of the IFC (Integer Factorization Cryptography) algorithm. 然后,您提到ECDHE,并询问.NET中的ECDiffieHellman(Cng)类,该类是关于椭圆曲线Diffie-Hellman ... IFC(整数分解密码)算法的ECC变体。

(IFC)DH definitely has a bootstrapping problem of picking a good (g, p) combination, and not being tricked by a man in the middle. (IFC)DH肯定存在选择良好(g, p)组合的引导问题,并且不会被中间的人欺骗。 For TLS the server side of the connection gets to make up whatever (g, p) it wants and then tells the client what it picked, but the client can't really tell if it's being tricked. 对于TLS,连接的服务器端可以组成所需的任何内容(g, p) ,然后将其选择的内容告诉客户端,但是客户端无法真正知道它是否受到欺骗。 If you own both sides you can solve this problem by generating a quality group in the 2048-bit space, and sticking with it. 如果双方都拥有,则可以通过在2048位空间中生成一个质量组并坚持下去来解决此问题。

There is no support for (IFC) Diffie-Hellman provided in-box in .NET. .NET内置的(IFC)Diffie-Hellman不支持。

ECDH has a different set of parameters, which are collectively called "the curve". ECDH具有一组不同的参数,这些参数统称为“曲线”。 For a prime curve (the most common form) the parameters are the tuple (p, a, b, G, n, h) (though really n and h are computations from (p, a, b, G) ), and then ECC math is defined on top of that . 对于素数曲线(最常见的形式),参数为元组(p, a, b, G, n, h) (尽管nh实际上是根据(p, a, b, G) ),然后ECC数学是在此之上定义的 Once ECC math is defined, ECDH is secret = X-Coordinate((alice * bob) * G) . 定义ECC数学后,ECDH是secret = X-Coordinate((alice * bob) * G) ECC has the same pitfalls as (IFC)DH, choosing bad values for the parameters can let tricks be played on the other party. ECC具有与(IFC)DH相同的陷阱,为参数选择错误的值可以让对方玩把戏。 Because of the potential trickery, and the fact that the domain parameters are large, choices of domain parameters get standardized into "named curves". 由于存在潜在的欺骗性,并且域参数很大,因此将域参数的选择标准化为“命名曲线”。 Two keys on the same curve, by definition, have the same set of domain parameters. 根据定义,同一条曲线上的两个关键点具有相同的域参数集。 In TLS you are only allowed to use the name (well, the Object Identifier value) of the curve. 在TLS中,仅允许使用曲线的名称(以及对象标识符值)。 The server pretty much gets to choose what set of parameters, but for maximum interoperability usually only three curves are chosen from (as of 2018): secp256r1 (aka NIST P-256), secp384r1 (aka NIST P-384), and secp521r1 (aka NIST P-521). 服务器几乎可以选择什么参数集,但是为了获得最大的互操作性,通常(截至2018年)仅选择三条曲线: secp256r1 (aka NIST P-256), secp384r1 (aka NIST P-384)和secp521r1 (又名NIST P-521)。

ECDiffieHellmanCng defaults to using secp521r1 , but you can control the curve in one of three different ways: ECDiffieHellmanCng默认使用secp521r1 ,但是您可以通过以下三种不同方式之一控制曲线:

Setting ecdh.KeySize 设置ecdh.KeySize

Changing the KeySize value (setting it to any value other than what it currently holds) results in generating a key onto a curve of that size. 更改KeySize值(将其设置为当前值以外的任何值)会导致在该大小的曲线上生成关键点。 This made total sense for Windows 7, 8, and 8.1... because Windows CNG only supported secp256r1 , secp384r1 , and secp521r1 . 这对于Windows 7、8和8.1完全有意义,因为Windows CNG仅支持secp256r1secp384r1secp521r1 So you can set KeySize to any of { 256, 384, 521 }. 因此,您可以将KeySize设置为{256,384,521}中的任何一个。

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

Creating it that way 这样创建

Windows 10 added support for more curves, and the sizes became ambiguous. Windows 10添加了对更多曲线的支持,并且大小变得模棱两可。 Does 256 mean secp256r1 or brainpoolp256r1 (or brainpoolp256t1 , numsp256t1 , secp256k1 , ...)? 256是secp256r1还是brainpoolp256r1 (或者brainpoolp256t1numsp256t1secp256k1 ...)? Okay, it means secp256r1 , and more complicated API exists. 好的,这意味着secp256r1 ,并且存在更复杂的API。

The ECDiffieHellman.Create factory has an overload (.NET Core 2.1+, .NET Framework 4.7+) which accepts an ECCurve . ECDiffieHellman.Create工厂有一个接受ECCurve的重载(.NET Core 2.1 + 、. NET Framework 4.7+)。 So another way to create a curve over secp384r1 would be 所以在secp384r1上创建曲线的另一种方法是

using (ECDiffieHellman ecdh = ECDiffieHellman.Create(ECCurve.NamedCurves.nistP384))
{
    ...
}

It can still be set later 以后仍然可以设置

Maybe you're using DI and can't use the factory nicely. 也许您正在使用DI,但不能很好地使用工厂。 Well, you can use the GenerateKey method (.NET Core 2.1+, .NET Framework 4.7+) to achieve the same results 好了,您可以使用GenerateKey方法(.NET Core 2.1 + 、. NET Framework 4.7+)来获得相同的结果

using (ECDiffieHellman ecdh = ECDiffieHellman.Create())
{
    ecdh.GenerateKey(ECCurve.NamedCurves.nistP384);
    ...
}

There are other ways of getting ECCurve values, such as ECCurve.CreateFromValue("1.3.132.0.34") or just manually building it from (p, a, b, G = (Gx, Gy), n, h) . 还有其他获取ECCurve值的方法,例如ECCurve.CreateFromValue("1.3.132.0.34")或仅通过(p, a, b, G = (Gx, Gy), n, h)手动构建它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM