为什么公钥BLOB在.net framework 4.7中以big endian格式包含密钥类型和密钥长度?

问题描述:

我写了下面的代码提取ECDH公共密钥团:为什么公钥BLOB在.net framework 4.7中以big endian格式包含密钥类型和密钥长度?

 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

Little-endian表示最低有效字节(0x45)首先出现。 – wRAR

前4个字节(密钥类型)是45434B31(十六进制格式)。

这将是0x45434B31(大端解释),或0x314B4345(小Endian解释)。 0x314B4345(LE)与链接页面中的nistP256条目匹配。

你的问题标题表明你相信长度被存储为big endian,但是你说的问题主体似乎是小端。 LE是正确的。 200000000x00000020(LE)或“32字节字段”。 32字节是256位,与nistP256的预期答案相匹配。


请注意,你真的不想使用这种blob格式。 NIST P-256,384和521曲线有不同的“魔术”值,但新的Windows 10附加曲线全部报告在0x504B4345(BCRYPT_ECDH_PUBLIC_GENERIC_MAGIC)之下。曲线名称必须由外部进行。

.NET中用于导入和导出键值的正确答案是通过ExportParametersImportParameters方法的ECParameters结构。

+0

对于我在密钥长度上的写法,你是正确的。但是,为什么当实际值显示为大端时,文档中说“魔术”(关键类型)应该是小尾数? – Raghu

+0

该文档将该值显示为数字常量。 Big/Little Endian是关于价值的存储。如果(在C中)你在x86/x64系统上写了'* blob = 0x314B4345',然后检查内存,它会显示为'45 43 4B 31' – bartonjs

+0

我同意你的看法,因为这是一个正常的存储问题。当我调用ToByteArray()并获得结果字节时,我不再解释字节(就像我已经完成的那样)。因此,为了一致性,我会将第一个字节8看作314B434520000000(而不是45434B3120000000)。我在这里错过了什么吗? – Raghu