ECDiffieHellmanCng PublicKey总是一样吗?

时间:2017-03-07 20:17:30

标签: c# cryptography

我正在使用C#ECDiffieHellmanCng类,并使用sample中的代码发现了(在我看来很奇怪)行为: 任何项目中生成的每个公钥都是一样的!这是正确的,是一种理想的行为吗?

示例:

using (ECDiffieHellmanCng bob = new ECDiffieHellmanCng())
            {
                bob.KeyDerivationFunction = ECDiffieHellmanKeyDerivationFunction.Hash;
                bob.HashAlgorithm = CngAlgorithm.Sha256;
                Trace.WriteLine(Encoding.UTF8.GetString(bob.PublicKey.ToByteArray()));
            }

跟踪将始终具有“ECK5B”作为输出。使用不同的构造函数只会稍微改变输出,但事实并非如此,它总是相同的。 我是否会理解某些内容并且此结果符合预期,并且没有机会提供随机公钥? 我只是觉得系统会使用更多的随机性。

1 个答案:

答案 0 :(得分:2)

ToByteArray()方法返回描述密钥的(特定于Windows的)CNG blob

blob布局是

UINT32 Magic
UINT32 cbKey
<cbKey bytes of public key>

BCRYPT_ECDH_PUBLIC_P521_MAGIC的值为0x354B4345,如果以Little-Endian顺序(45 43 4B 35)查看,则为ASCII字符串ECK5。 NIST P-521曲线上某点的x坐标最多需要521位,或((521 + 7)/ 8)= 66个字节。 Little-Endian中的(UINT32)6642 00 00 00。因此,所有字节数组(对于基于NIST P-521的公钥)都将以

开头
45 43 4B 35 42 00 00 00

(然后有66个字节的ECPoint的X组件)。由于ASCII字符串在读取第一个0x00时将终止,因此将其解释为(作为字符串)为ECK5B

正如您已经发现的,此值实际上不是字符串,因此为了将其视为一个字符串,需要将其编码为字符串安全格式,例如hex或Base64。由于hex是1 =&gt; 2编码(或1 =&gt; ~3,带有空格),而Base64是3 =&gt; 4编码,因此大多数应用程序最终使用Base64。