2010-09-14 127 views
6

给定一个像SHA1或SHA256这样的散列算法我该如何去获取RFC3447中定义的ASN.1 DER编码? (见第42页 - link)以下是所需的输出。C# - 如何计算特定散列算法的ASN.1 DER编码?

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转换程序#(或硬编码它们)。有任何想法吗?

+0

目前还不清楚“给定散列算法”的含义。你的意思是把哈希算法的名字作为一个字符串?您可以将虚线字符串Oid表示法转换为字节,但您仍然需要使用常见哈希算法Oids的硬编码映射。 – 2010-09-15 01:35:41

+0

输入可能是HashAlgorithm,字符串或Oid。期望的结果是一个与编码格式匹配的byte []。 – 2010-09-15 02:10:39

回答

13

这将让你的方式部分:

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 

然后你只需要插入它在序列标题(30<length>30<length2><oid>050004<hashlength>)。

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


编辑:的详细原因:

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

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

其中

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

所以从开始在里面:摘要算法标识符包括一个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个字节 - 这就是上面的内容。

我们现在可以继续使用DigestInfo的其余部分:一个OCTET STRING,它包含哈希的值。 SHA-1的20字节散列将被编码为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>

如果您需要自己生成它,现在应该可以看到length2 = encodedOid.Length + 2和length = length2 + 2 + 2 + hashlength。

如果您需要更多关于ASN.1编码的信息,我可以推荐Burt Kaliski的A Layman's Guide to a Subset of ASN.1, BER, and DER