C # - How to calculate ASN.1 DER encoding of a specific hashing algorithm?

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

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 

I hope there is some reasonable way to do this in C # that does not require me to write an OID for the ASN.1 DER conversion (or hard code). Any ideas?

+6
c # cryptography
source share
1 answer

This will help you partially:

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

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

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


EDIT: A few more details:

The ASN.1 you want to encode is as follows:

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

Where

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

So, to start from the inside out: digest-AlgorithmIdentifier consists of SEQUENCE -tag (30), length (we'll get back to that), OID and some parameters. The OID for fx 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 OID encoding). All regular hash functions have NULL as parameters, which are encoded as 05 00 . Thus, the AlgorithmIdentifier contains 9 bytes - this is higher.

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

DigestInfo content length is now 11 + 22 bytes (). We need to run DigestInfo using the SEQUENCE -tag, so in the end we get: 30 21 30 09 06 05 2b 0w 02 01 1a 05 00 04 20 <HASH> .

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

If you need more information about ASN.1 encoding, I can recommend the Burt Kaliski Layman Guide for a subset of ASN.1, BER, and DER .

+13
source share

All Articles