我编写了以下代码来提取ECDH公钥blob:
var curve = ECCurve.NamedCurves.nistP256;
ECDiffieHellman ecdh = ECDiffieHellman.Create(curve);
var bytes = ecdh.PublicKey.ToByteArray();
Console.WriteLine($"Public Key (byte length with format info): {bytes.Length}");
var hexString = BitConverter.ToString(bytes).Replace("-", string.Empty);
Console.WriteLine($"Public Key (hex with format info): {hexString}");
我得到了以下输出:
公钥(格式信息的字节长度):72
公钥(带格式信息的十六进制):45434B3120000000C3F1AC1F3D272BE14A26BE35B1A31F6C969425259162C06BEBE6AE977809984FC509ED5154E1E4782079D4BDDCDA6E083E48D271755267AD765CAD0E66B9FD9F
前4个字节(密钥类型)是45434B31(十六进制格式)。这似乎是大端格式,其中this MSDN link表示它应该是小端格式,这表明这4个字节应该是314B4345(再次,如此链接所示)。链接也使用“魔术”,而不是“键类型”。接下来的4个字节是20000000(十六进制格式)似乎是小端格式(如上面的链接所示)。
为什么键类型被格式化为大端有合理的解释吗?或者我在这里遗漏了什么?
答案 0 :(得分:1)
前4个字节(密钥类型)是45434B31(十六进制格式)。
那将是0x45434B31
(Big Endian解释),或0x314B4345
(Little Endian解释)。 0x314B4345
(LE)与链接页面中的nistP256条目匹配。
你的问题标题表明你认为长度是存储大端,但你的问题正文你说它似乎是小端。 LE是对的。 20000000
是0x00000020
(LE)或“32字节字段”。 32个字节是256位,与nistP256的预期答案相匹配。
请注意,您确实不想使用此blob格式。 NIST P-256,384和521曲线获得了明显的“魔术”值,但新的Windows 10附加曲线都报告在0x504B4345(BCRYPT_ECDH_PUBLIC_GENERIC_MAGIC)下。曲线名称必须在外部进行。
.NET上用于导入和导出键值的正确答案是通过ECParameters
和ExportParameters
方法的ImportParameters
结构。