What is needed to convert ASN.1 data to a Public K

2019-01-25 22:41发布

问题:

This code relates to DKIM signature verification used in anti-spam efforts.

I have a byte[] from s1024._domainkey.yahoo.com that is ASN.1 encoded, but I don't know if that alone contains enough information to materialize a public key.

Based on this class, it appears I can convert an ASN.1 key into a X509Certificate Public key, but I need to supply an OID and some ASN.1-encoded parameters.

In this example I have metadata that the ASN1 key is:

  1. An RSA encoded key (ASN.1 DER-encoded [ITU-X660-1997] RSAPublicKey per RFC3447)
  2. Used with either sha1 sha256 hash algorithms
  3. Uses an OID relating to the following table from section A.2 of RFC3447 (though I don't know how to turn this information into a full OID)
/*
 * 1.2.840.113549.1
 * 
    MD2 md2WithRSAEncryption    ::= {pkcs-1 2}
    MD5 md5WithRSAEncryption    ::= {pkcs-1 4}
    SHA-1 sha1WithRSAEncryption   ::= {pkcs-1 5}
    SHA-256 sha256WithRSAEncryption ::= {pkcs-1 11}
    SHA-384 sha384WithRSAEncryption ::= {pkcs-1 12}
    SHA-512 sha512WithRSAEncryption ::= {pkcs-1 13}
 */

Code sample

string pubkey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDrEee0Ri4Juz+QfiWYui/E9UGSXau/2P8LjnTD8V4Unn+2FAZVGE3kL23bzeoULYv4PeleB3gfmJiDJOKU3Ns5L4KJAUUHjFwDebt0NP+sBK0VKeTATL2Yr/S3bT/xhy+1xtj4RkdV7fVxTn56Lb4udUnwuxK4V5b5PdOKj/+XcwIDAQAB";
byte[] pubkeyByteArray = Convert.FromBase64String(pubkey);
AsnEncodedData aData = new AsnEncodedData(pubkeyByteArray);

// OID must not be null, but it is here.  What is it?
System.Security.Cryptography.X509Certificates.PublicKey pubKeyRdr = new System.Security.Cryptography.X509Certificates.PublicKey(aData.Oid, null, aData);

Question

  • What OID should I use?
  • What are examples of ASN.1 parameters?

回答1:

Update

This is the data you have provided when it is parsed using the link @erickson provided:

SEQUENCE (2 elem)
    SEQUENCE (2 elem)
        OBJECT IDENTIFIER 1.2.840.113549.1.1.1
        NULL
    BIT STRING (1 elem)
        SEQUENCE (2 elem)
            INTEGER(1024 bit)
            INTEGER 65537

The reason the previous code throws a ASN1 bad tag value met. exception is because aData contains incorrect data (contains all the data above). From what I've seen, the is how the 3 arguments to System.Security.Cryptography.X509Certificates.PublicKey are broken down.

  1. The first parameter is the OID, which is the OBJECT IDENTIFIER above.
  2. The second parameter is the public key parameters. In the parsing above, you can see it is NULL.
  3. The third parameter is actual public key value. This is made up of the third sequence above. The sequence has 2 integers, a 1024-bit modulus followed by the public exponent.

I tested it using the code below. I couldn't find a built-in method to parse the data without writing a DER parser.

Oid oid = new Oid("1.2.840.113549.1.1.1");
AsnEncodedData keyValue = new AsnEncodedData(getBytes("30818902818100EB11E7B4462E09BB3F907E2598BA2FC4F541925DABBFD8FF0B8E74C3F15E149E7FB6140655184DE42F6DDBCDEA142D8BF83DE95E07781F98988324E294DCDB392F82890145078C5C0379BB7434FFAC04AD1529E4C04CBD98AFF4B76D3FF1872FB5C6D8F8464755EDF5714E7E7A2DBE2E7549F0BB12B85796F93DD38A8FFF97730203010001"));
AsnEncodedData keyParam = new AsnEncodedData(new byte[] {05, 00});
PublicKey pubKeyRdr = new System.Security.Cryptography.X509Certificates.PublicKey(oid, keyParam, keyValue);
System.Diagnostics.Debug.WriteLine(pubKeyRdr.Key.KeyExchangeAlgorithm);
System.Diagnostics.Debug.WriteLine(pubKeyRdr.Key.KeySize);

It outputs RSA-PKCS1-KeyEx and 1024.



回答2:

What you have is a SubjectPublicKeyInfo structure. It looks like this:

Sequence {
  Sequence {
    Oid: 1.2.840.113549.1.1.1
    Parameters: null
  }
  KeyValue: blah blah
}

The oid for RSA keys is 1.2.840.113549.1.1.1.

For an RSA key, there are no parameters, so this is null.

However, I don't see any API on AsnEncodedData to parse apart the elements and get at what you need.