2010-09-14 12 views
6

Dado un algoritmo hash como SHA1 o SHA256, ¿cómo podría obtener la codificación DER ASN.1 para él como se define en RFC3447? (vea la página 42 - link) A continuación se muestra el resultado deseado.C# - ¿Cómo calcular la codificación DER ASN.1 de un algoritmo hash en particular?

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 

Estoy esperando que hay alguna manera inteligente de hacer esto en C# que no me requiere para escribir un OID de ASN.1 DER rutina de conversión (o codificar ellos). ¿Algunas ideas?

+0

No está claro a qué se refiere con "dado un algoritmo hash". ¿Quiere decir dado el nombre del algoritmo hash como una cadena? Puede convertir de la notación Oid de cadena punteada a bytes, pero aún necesita una asignación codificada del algoritmo hash común Oids. –

+0

La entrada podría ser un HashAlgorithm, una cadena o un Oid. El resultado deseado es un byte [] que coincide con el formato codificado. –

Respuesta

13

Esto le dará una parte del camino:

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 

A continuación, sólo tendrá que introducir en la secuencia-encabezamiento (30<length>30<length2><oid>050004<hashlength>).

Por supuesto, si desea crear una firma RSA PKCS # 1 v1.5, sería mejor que simplemente usando RSAPKCS1SignatureFormatter.


EDIT: Algunos detalles más:

El ASN.1 que quiere codificar es la siguiente:

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

donde

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

Así que para empezar desde adentro: el digest-AlgorithmIdentifier consiste en un SEQUENCE -tag (30), una longitud (volveremos a eso), un OID y algunos parámetros. El OID para f.x. SHA-1 es 1.3.14.3.2.26, que está codificado como 06 05 2b 0e 03 02 1a (OID-tag 06, longitud 5 y la codificación del OID). Todas las funciones hash habituales tienen NULL como parámetros, que se codifica como 05 00. Entonces, el AlgorithmIdentifier contiene 9 bytes; esto es lo anterior.

Ahora podemos continuar con el resto de DigestInfo: una CADENA DE OCTETOS, que contiene el valor del hash. El hash de 20 bytes de SHA-1 se codificará como 04 20 <HASH>.

La longitud de los contenidos de DigestInfo ahora es de 11 + 22 bytes(). Necesitamos comenzar el DigestInfo con el SEQUENCE -tag, así que terminamos con: 30 21 30 09 06 05 2b 0w 02 01 1a 05 00 04 20 <HASH>.

Si necesita generarlo usted mismo, ahora debería poder ver ese length2 = encodedOid.Length + 2 y esa longitud = length2 + 2 + 2 + hashlength.

Si necesita más información sobre la codificación de ASN.1, puedo recomendar A Layman's Guide to a Subset of ASN.1, BER, and DER de Burt Kaliski.

Cuestiones relacionadas