C# - 如何计算特定哈希算法的 ASN.1 DER 编码?

时间:2023-03-26
本文介绍了C# - 如何计算特定哈希算法的 ASN.1 DER 编码?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

给定像 SHA1 或 SHA256 这样的哈希算法,我将如何获得 RFC3447 中定义的 ASN.1 DER 编码?(参见第 42 页 - 链接)下面是所需的输出.

Given a hash algorithm like SHA1 or SHA256 how would I go about obtaining the ASN.1 DER encoding for it as defined in RFC3447? (see page 42 - link) Below is the desired output.

MD5        30 20 30 0c 06 08 2a 86 48 86 f7 0d 02 05 05 00 04 10
SHA-1      30 21 30 09 06 05 2b 0e 03 02 1a 05 00 04 14
SHA-256    30 31 30 0d 06 09 60 86 48 01 65 03 04 02 01 05 00 04 20
SHA-384    30 41 30 0d 06 09 60 86 48 01 65 03 04 02 02 05 00 04 30
SHA-512    30 51 30 0d 06 09 60 86 48 01 65 03 04 02 03 05 00 04 40

我希望在 C# 中有一些智能方法可以做到这一点,不需要我编写 Oid 到 ASN.1 DER 转换例程(或硬编码它们).有什么想法吗?

I'm hoping there is some intelligent way to do this in C# that doesn't require me to write an Oid to ASN.1 DER conversion routine (or hardcode them). Any ideas?

推荐答案

这将为您提供帮助:

string oidString = CryptoConfig.MapNameToOID(hashName); // f.x. "MD5"
byte[] encodedOid = CryptoConfig.EncodeOID(oidString); // Gives you f.x. 06 08 2a 86 48 86 f7 0d 02 05

然后你只需要把它插入到 SEQUENCE-heading (3030).

Then you just need to insert it in the SEQUENCE-heading (30<length>30<length2><oid>050004<hashlength>).

当然,如果您想创建 RSA PKCS#1 v1.5 签名,最好只使用 RSAPKCS1SignatureFormatter.

Of course if you want to create an RSA PKCS#1 v1.5 signature, you would be better off just using RSAPKCS1SignatureFormatter.

更多细节:

您要编码的 ASN.1 是这样的:

The ASN.1 you want to encode is this:

DigestInfo ::= SEQUENCE {
      digestAlgorithm AlgorithmIdentifier,
      digest OCTET STRING
}

在哪里

AlgorithmIdentifier  ::=  SEQUENCE  {
      algorithm               OBJECT IDENTIFIER,
      parameters              ANY DEFINED BY algorithm OPTIONAL  
}

所以从内部开始:digest-AlgorithmIdentifier 由一个 SEQUENCE-tag (30)、一个长度(我们将回到那个)、一个 OID 和一些参数组成.f.x 的 OID.SHA-1为1.3.14.3.2.26,编码为06 05 2b 0e 03 02 1a(OID-tag 06,长度5,OID的编码).所有常用的散列函数都有NULL作为参数,编码为05 00.所以 AlgorithmIdentifier 包含 9 个字节 - 这是上面的.

So to start from inside: the digest-AlgorithmIdentifier consist of a SEQUENCE-tag (30), a length (we will get back to that), an OID and some parameters. The OID for f.x. SHA-1 is 1.3.14.3.2.26, which is encoded as 06 05 2b 0e 03 02 1a (OID-tag 06, length 5 and the encoding of the OID). All the usual hash functions have NULL as parameters, which is encoded as 05 00. So the AlgorithmIdentifier contains 9 bytes - this is the above.

我们现在可以继续处理 DigestInfo 的其余部分:一个 OCTET STRING,其中包含哈希值.SHA-1 的 20 字节哈希将被编码为 04 20 .

We can now continue with the rest of the DigestInfo: an OCTET STRING, which contains the value of the hash. SHA-1's 20 bytes hash will be encoded as 04 20 <HASH>.

DigestInfo 内容的长度现在是 11+22 字节 ().我们需要以 SEQUENCE-tag 开始 DigestInfo,因此我们最终得到:30 21 30 09 06 05 2b 0w 02 01 1a 05 00 04 20 <HASH>.

The length of the contents of the DigestInfo is now 11+22 bytes (). We need to start the DigestInfo with the SEQUENCE-tag, so we end up with: 30 21 30 09 06 05 2b 0w 02 01 1a 05 00 04 20 <HASH>.

如果您需要自己生成它,您现在应该能够看到 length2 = encodedOid.Length + 2 并且该 length = length2 + 2 + 2 + hashlength.

If you need to generate it yourself, you should now be able to see that length2 = encodedOid.Length + 2 and that length = length2 + 2 + 2 + hashlength.

如果您需要有关编码 ASN.1 的更多信息,我可以推荐 Burt Kaliski 的 AASN.1、BER 和 DER 子集的外行指南.

If you need some more information about encoding ASN.1, I can recommend Burt Kaliski's A Layman's Guide to a Subset of ASN.1, BER, and DER.

这篇关于C# - 如何计算特定哈希算法的 ASN.1 DER 编码?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!