La struttura ASN.1 di cui stiamo parlando è:
DigestInfo ::= SEQUENCE {
digestAlgorithm AlgorithmIdentifier,
digest OCTET STRING
}
AlgorithmIdentifier ::= SEQUENCE {
algorithm OBJECT IDENTIFIER,
parameters ANY DEFINED BY algorithm OPTIONAL
}
Quando codificati in DER, il vero valore di hash (i byte grezzi) si troverà alla fine della struttura codificata. Quindi la codifica DER della struttura, per una determinata funzione di hash, equivale a concatenare una stringa fissa di byte con il valore hash. La stringa di byte per varie funzioni hash viene fornita in extenso in PKCS # 1 (sezione 9.2, pagina 38 della versione 2.1 dello standard).
Quindi, su un sistema simile a Unix, per ottenere dal valore hash contenuto nel file hash-value.bin
alla struttura con codifica DER che specifica SHA-256, dovresti fare questo:
(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
Il diavolo si nasconde nei dettagli, e ASN.1 è così pieno di dettagli che dovrebbe essere giustamente bruciato sul rogo. In questo caso, nota come il campo parameters
è contrassegnato come OPTIONAL
. In una versione molto più vecchia di un altro standard, un errore tipografico ha comportato l'omissione di quella parola chiave; quindi, alcuni implementatori hanno scoperto che avevano per includere alcuni parametri, anche se l'OID era sufficiente per designare la funzione di hash. Quindi, hanno aggiunto un valore ASN.1 NULL
come parametri (viene visualizzato come 0x05 0x00
byte nelle intestazioni codificate). Tuttavia, alcuni implementatori successivi lo hanno trovato in grado di "correggere" il problema e omettere del tutto i parametri non necessari, come consentito dalla parola chiave OPTIONAL
. La linea di fondo è la seguente: per una determinata funzione di hash, ci sono due versioni della "stringa di intestazione fissa" da concatenare con il valore di hash. Ad esempio, per SHA-256, PKCS # 1 dice che l'intestazione è:
30 31 30 0d 06 09 60 86 48 01 65 03 04 02 01 05 00 04 20
ma si può anche incontrare questa intestazione alternativa:
30 2f 30 0b 06 09 60 86 48 01 65 03 04 02 01 04 20
che alcune implementazioni usano. Secondo PKCS # 1, deve usare il primo quando si produce la firma, ma anche deve accettarlo quando si verificano le firme.