C#ECDsaCng.SignData在OpenSSL中使用签名

本文关键字:SignData OpenSSL C#ECDsaCng | 更新日期: 2023-09-27 17:59:46

我需要知道的编码

https://msdn.microsoft.com/en-us/library/bb347054(v=vs.110).aspx

ECDsaCng.SignData Method (Byte[])

默认情况下用于其字节数组,以及如何将其转换为接受的DER格式

https://www.openssl.org/docs/manmaster/crypto/i2d_ECDSA_SIG.html

以便我可以使用方法CCD_ 1在OpenSSL中验证我的C#生成的ECDSA签名。

我知道它的SHA1,我知道如何加载摘要,我只是不知道ECDsaCng.SignData方法的字节编码是什么,也不知道如何将其转换为DER格式,如果我需要的话。

C#ECDsaCng.SignData在OpenSSL中使用签名

ECDSA签名是值对(r, s)

Windows CNG将其作为两个值的串联发出,由于.NET不会重新解释数据,因此这是事实上的.NET格式。(r是阵列的前半部分,s是后半部分)

OpenSSL需要一个DER编码的SEQUENCE结构(整数(r),整数(s))。这大致意味着{ 0x30, payload_length, 0x02, r_length, r_bytes[0]...r_bytes[r_length-1], 0x02, s_length, s_bytes[0]...s_bytes[s_length-1] };尽管它比这稍微复杂一些,因为当r_bytes[0]或s_bytes[0]>=0x80时需要填充字节(因为这会使它显示为负数)。

不幸的是,默认情况下,框架中没有公开通用的DER编码器。

如果您试图在Linux上运行,那么使用.NET Core可能会更好,因为Linux的ECDSA实现已经完成了数据转换。

以下是TLSSigAPI.cs使用.Net生成符号并使用OpenSSL进行验证的代码。

也许能帮你。

byte[] rawDataHash = SHA256(rawData);
byte[] rawSig = ecdsa.SignHash(rawDataHash);
int halfLength = rawSig.Length / 2;
byte[][] rEncoded = SegmentedEncodeUnsignedInteger(rawSig, 0, halfLength);
byte[][] sEncoded = SegmentedEncodeUnsignedInteger(rawSig, halfLength, halfLength);
List<byte[][]> items = new List<byte[][]>() { rEncoded, sEncoded };
byte[] opensslSig = ConstructSequence(items);