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