La estructura ASN.1 de la que estamos hablando aquí es:
DigestInfo ::= SEQUENCE {
digestAlgorithm AlgorithmIdentifier,
digest OCTET STRING
}
AlgorithmIdentifier ::= SEQUENCE {
algorithm OBJECT IDENTIFIER,
parameters ANY DEFINED BY algorithm OPTIONAL
}
Cuando esté codificado en DER, el valor de hash real (los bytes en bruto) se ubicará al final de la estructura codificada. Entonces, la codificación DER de la estructura, para una función hash dada, es equivalente a concatenar una cadena fija de bytes con el valor hash. La cadena de bytes para varias funciones hash se dan in extenso en PKCS # 1 (sección 9.2, página 38 de la versión 2.1 de la norma).
Entonces, en un sistema similar a Unix, para obtener del valor hash contenido en el archivo hash-value.bin
a la estructura codificada en DER que especifica SHA-256, debería hacer esto:
(printf '\x30\x31\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\x05\x00\x04\x20' ; cat hash-value.bin) > encoded-hash.der
El diablo se esconde en los detalles, y ASN.1 está tan lleno de detalles que debería ser quemado en la estaca. En este caso, observe cómo el campo parameters
está marcado como OPTIONAL
. En una versión mucho más antigua de otro estándar, un error tipográfico resultó en la omisión de esa palabra clave; por lo tanto, algunos implementadores encontraron que tenían incluir algunos parámetros, incluso así el OID era suficiente para designar la función hash. Por lo tanto, agregaron un valor de ASN.1 NULL
como parámetros (se muestra como 0x05 0x00
bytes en los encabezados codificados). Sin embargo, algunos implementadores posteriores consideraron que era adecuado "corregir" el problema y omitir los parámetros innecesarios por completo, como lo permite la palabra clave OPTIONAL
. La línea de fondo es la siguiente: para una función hash dada, hay dos versiones de la "cadena de encabezado fija" que se deben concatenar con el valor de hash. Por ejemplo, para SHA-256, PKCS # 1 dice que el encabezado es:
30 31 30 0d 06 09 60 86 48 01 65 03 04 02 01 05 00 04 20
pero uno también puede encontrar este encabezado alternativo:
30 2f 30 0b 06 09 60 86 48 01 65 03 04 02 01 04 20
que utilizan algunas implementaciones. De acuerdo con PKCS # 1, usted deberá utilizar el primero al producir la firma, pero también deberá aceptar ambas al verificar las firmas.