问题描述
给定像 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 (30
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 编码?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!