C# - How to calculate ASN.1 DER encoding of a particular hash algorithm?

前端 未结 1 1523
轻奢々
轻奢々 2020-12-31 17:57

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 outp

相关标签:
1条回答
  • 2020-12-31 18:24

    This will get you part of the way:

    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
    

    Then you just need to insert it in the SEQUENCE-heading (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 just using RSAPKCS1SignatureFormatter.


    EDIT: A few more details:

    The ASN.1 you want to encode is this:

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

    where

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

    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.

    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>.

    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>.

    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.

    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.

    0 讨论(0)
提交回复
热议问题