我正在使用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”作为输出。使用不同的构造函数只会稍微改变输出,但事实并非如此,它总是相同的。 我是否会理解某些内容并且此结果符合预期,并且没有机会提供随机公钥? 我只是觉得系统会使用更多的随机性。
答案 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)66
是42 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。