Analizar un hash de firma separada PKCS7

6

Estoy tratando de verificar manualmente las firmas de los archivos de Apple iOS Passbook, que son firmas independientes PKCS # 7 de la clave RSA del desarrollador de Apple que creó el archivo.

Lo que significa que hay un archivo "firma" que es la firma separada de un archivo "manifest.json". Estoy utilizando el archivo pkpass "Titanic boarding pass" de enlace para la prueba. Haciendo:

openssl smime -verify -in signature -content manifest.json -inform der -noverify

regresa con éxito, así que sé que la firma debe ser válida. Ahora, al analizar el archivo signature , puedo haber descodificado los datos ASN.1 codificados en DER y muestra que el atributo que se está firmando es un resumen SHA1 del mensaje, lo que resulta en 733538fde88843c7ad24fb71674dbdd372df7b4d1 . La ejecución de openssl sha1 manifest.json muestra que, de hecho, el SHA1 de ese archivo es de hecho 7335...b4d1 .

Ahora, analizando el SignerInfo bits de signature , puedo tomar el OctetString que es el cifrado RSA de su firma:

BC C5 F9 F2 53 FD 2C 13 EA CE 64 BB 89 85 60 82 78 63 5B 04 FA F8 BF 7E 2A 6C 20 
5D C3 C8 E8 8A 2F E3 4D B9 8E 1C A1 42 DF 2B 46 89 76 63 0B 8A DD E5 8A 69 4E D0
CF 3F E7 36 1E F8 7F 49 0D 27 EC 0F 73 76 5D 62 A1 4E 8A 43 AB EC ED 2E CD E7 69
3F AD 32 48 0A 79 52 DB 36 5B 61 94 71 3F B3 09 1E 80 17 94 31 06 AF E6 A3 A5 A0
D6 B7 71 31 ED 4C 6F C1 5C B6 4B 79 E5 7A BA BC 1D AD BB D2 F7 39 05 16 73 2C AE
74 E3 9C 4F 7E A7 B1 90 38 FC 92 78 9F 70 C0 D0 94 83 83 EC 01 F4 B6 16 36 4B EE
BC BA DD AC 23 64 4B C2 93 21 9E 9B 21 64 9E 7C 1B 72 87 0B C1 7D 9C 6A 9B AA AB
36 67 F8 7C 7B 8D 9E 88 FC 95 C8 29 57 8B EB B9 5C F6 AB 59 64 CA 87 ED DE 50 BA
67 C0 26 F8 5B FD 47 10 B0 A6 4E D8 D6 F0 E9 A0 DE 2B 6B D4 84 2A 91 A6 A7 27 22
CE D6 5F D2 C7 87 56 A4 E6 E4 D6 D3 C9

Usando la clave pública del certificado anterior en el archivo signature :

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzEjQiB/QgOWX2QF6CGtCiq1ZDyRzJJKJ
4ZW6cuF2MdtOi4If+IhTHcVkdeJ+/cacuRFcscNOXODjriCbAbmTVYTFx290n4vQ1qvPuu3/T41f
4dZHvAM9dmUHuN7M/f/SyGWJiFSYj3VY7S+jyH5zvskGp84YNkHB/Uky3ZFZElOwoOltRNVL25Rw
52nIMVrqO+Cyn2T2LSkk/6yjSll46TyjYuTDEev4XvYhIQBfbraP9rUabRkf1k0EuXl7qM2GeKGM
vq9sQwMRPVFFM2Fa/8xUeA4D/4AWR4S4shuVUxWOx8bq57RNRDogTr4rotaAOyDACu0aS37fWJmQ
zExr3QIDAQAB
-----END PUBLIC KEY-----

Puedo decodificar exitosamente el cifrado RSA y obtener un resultado. El resultado del descifrado es otra cadena codificada en ASN.1 DER, que es:

30 21 30 09 06 05 2B 0E 03 02 1A 05 00 04 14 5B AC 45 51 B9 A5 51 68 28 89
51 59 1F 62 31 9B A7 15 50 CB

Al analizar eso, indica que 5bac4551b9a55168288951591f62319ba71550cb es el hash SHA1 de algo. Pero ese no es el SHA1 de manifest.json ( 5bac...50cb ! = 7335...b4d1 ).

Entonces, ¿a qué se supone que debo comparar ese SHA1 descifrado? Sé que el propietario de ese certificado cifró esta cadena codificada en DER particular, pero no veo cómo coinciden. ¿Qué parte del proceso RSA / PKCS7 me estoy perdiendo aquí?

    
pregunta MidnightLightning 29.10.2012 - 18:44
fuente

1 respuesta

4

El cálculo del resumen se describe en CMS (el nuevo nombre para PKCS # 7), sección 5.4. Es decir, cuando hay atributos firmados, entonces lo que está firmado es una codificación del conjunto de atributos; dado que uno de los atributos contiene el hash del archivo de datos en el que se aplica el objeto de firma, esta firma se extiende al archivo de datos. Ver este párrafo:

  

Una codificación separada      del campo signedAttrs se realiza para el cálculo del resumen del mensaje.      La etiqueta IMPLICIT [0] en signedAttrs no se usa para el DER      codificación, más bien se utiliza una etiqueta EXPLICIT SET OF. Es decir, el DER      codificación de la etiqueta EXPLICIT SET OF, en lugar de IMPLICIT [0]      etiqueta, DEBE incluirse en el cálculo del resumen del mensaje junto con      la longitud y los octetos de contenido del valor SignedAttributes.

por lo que el hash debe calcularse sobre la codificación completa del valor SignedAttributes , excepto que reemplaza el primer byte (que debería ser 0xA0) con el byte que codifica una etiqueta universal SET OF (eso es 0x31, si I recuerda correctamente).

    
respondido por el Thomas Pornin 29.10.2012 - 20:12
fuente

Lea otras preguntas en las etiquetas