Clave de descifrado de correo electrónico SMIME con OpenSSL

9

Me gustaría saber si es posible usar el comando openssl para recuperar y descifrar la clave para cifrar / descifrar el contenido del correo electrónico. Sé que puedo descifrar todo el correo cifrado por algo como esto

openssl smime -decrypt -in enc_mail.eml -inkey recip_priv.pem > dec_mail.eml

Sin embargo, me gustaría ver los pasos intermedios. Si entiendo bien el procedimiento, el contenido real del correo electrónico no se cifra mediante la clave pública del destinatario, sino con la clave generada aleatoriamente en el lado del remitente. Esta clave luego se cifra con la clave de acceso del destinatario y se adjunta al mensaje cifrado. Estoy en lo cierto ¿Es posible usar openssl para mostrarme la clave cifrada adjunta y descifrarla por separado?

Gracias.

    
pregunta Jakub Žitný 09.11.2013 - 19:38
fuente

2 respuestas

9

Sí, puedes. Este ejemplo utiliza openssl smime con el CBC de RC2 predeterminado con una clave de 40 bits. El nuevo cms sub-command se comporta de manera ligeramente diferente , y utiliza 3- DES por defecto. Probablemente no debería utilizar ninguno de esos algoritmos para cifrar datos importantes ;-)

Hay dos advertencias menores: en primer lugar, también usaré un par de otras herramientas (aunque OpenSSL se usa para todo el trabajo pesado), y en segundo lugar, voy a hacer Algunas suposiciones sobre cómo se cifró el correo electrónico.

La en / desencriptación es similar a la mayoría de los métodos que usan RSA: use RSA (lento, costoso) para en / desencriptar una clave simétrica, y use la clave simétrica rápida para en / desencriptar los datos reales. (Consulte esta pregunta o esto para más antecedentes).

Tome su correo electrónico, extraiga la parte P7M y descodifíquelo. Si tiene una sola parte .p7m que está codificada en base64, puede hacerlo fácilmente con metamail :

$ metamail -wy enc_mail.eml

Guarda el archivo P7M. Este es un ASN.1 DER codificado CMS (PKCS # 7), para que podamos mirar dentro:

  $ dumpasn1 -tilda  smime.p7m
   0 1946: SEQUENCE {
   4    9: . OBJECT IDENTIFIER envelopedData (1 2 840 113549 1 7 3)
         : . . (PKCS #7)
  15 1931: . [0] {
                  [ .. certificate details and whatnot omitted ...]
 188   13: . . . . . SEQUENCE {
 190    9: . . . . . . OBJECT IDENTIFIER rsaEncryption (1 2 840 113549 1 1 1)
         : . . . . . . . (PKCS #1)
 201    0: . . . . . . NULL
         : . . . . . . }
 203  256: . . . . . OCTET STRING    
         : . . . . . . A0 DA EA FB EA 1A 0F 81    ........
         : . . . . . . F4 30 9F 78 5C 9B A7 27    .0.x\..'
                       [ ... blob snipped ...]
 463 1483: . . . SEQUENCE {
 467    9: . . . . OBJECT IDENTIFIER data (1 2 840 113549 1 7 1)
         : . . . . . (PKCS #7)
 478   26: . . . . SEQUENCE {
 480    8: . . . . . OBJECT IDENTIFIER rc2CBC (1 2 840 113549 3 2)
         : . . . . . . (RSADSI encryptionAlgorithm)
 490   14: . . . . . SEQUENCE {
 492    2: . . . . . . INTEGER 160
 496    8: . . . . . . OCTET STRING 3E EA 0E 12 37 A8 56 70                 
         : . . . . . . }
         : . . . . . }
 506 1440: . . . . [0]    
         : . . . . . A5 FF A1 70 2C AD 82 6A    ...p,..j
         : . . . . . C7 F0 84 E8 9E 93 8F 53    .......S
                     [... blob snipped ...]

Estoy usando dumpasn1 porque openssl asn1parse no está decidido a mostrar o volcar los diversos blobs que nos interesan. La estructura de su correo electrónico variará de la anterior, por supuesto. Las columnas 1 y 2 son el desplazamiento y el tamaño de cada subestructura (posiblemente anidada).

Las partes interesantes están en compensaciones:

  • 188 los detalles de cifrado RSA, seguidos de la compensación 203 por los datos cifrados
  • 463 los detalles y parámetros de cifrado S / MIME (RC2 CBC)
  • 506 el blob encriptado

En el desplazamiento 188 podemos ver que se usa RSA, seguido de 256 bytes de datos, así que extraiga ese blob de datos (desplazamiento 203) y conviértalo a binario:

$ dumpasn1 -a -203 smime.p7m | tail -qn +2 | xxd -r -p > rsa.bin

(Observe que el offset de inicio -203 y el uso de tail para omitir la primera línea de salida. Esto es un poco complicado, pero desafortunadamente tanto dumpasn1 como openssl asn1parse dejan intacto el prefijo de tipo-longitud cuando intenta cortar y cortar objetos.)

Descifre estos datos utilizando RSA:

$ openssl rsautl -inkey recip_priv.pem -in rsa.bin -decrypt -out rc2key.bin
$ xxd -u -p  rc2key.bin
92F6EB53B1

En este caso obtenemos una salida de 5 bytes (40 bits), la clave simétrica que necesitamos. La entrada fue PKCS # 1 v1.5 rellenada (ver §8.1) para varias razones , por lo tanto, la disparidad de tamaño.

La carga útil principal (correo electrónico) está en el blob en la compensación 506, extraiga eso en un archivo:

$ dumpasn1 -a -506 smime.p7m | tail -qn +2 | xxd -r -p > email.bin

Ahora aquí está el bit un poco complicado, para RC2 consulte la sección 6 de RFC 2268 :

rc2CBC OBJECT IDENTIFIER
 ::= {iso(1) member-body(2) US(840) rsadsi(113549)
      encryptionAlgorithm(3) 2}

RC2-CBCParameter ::= CHOICE {
  iv IV,
  params SEQUENCE {
    version RC2Version,
    iv IV
  }
}

RC2Version ::= INTEGER -- 1-1024
IV ::= OCTET STRING -- 8 octets

Esto explica la estructura de datos en el desplazamiento 490:

 480    8: . . . . . OBJECT IDENTIFIER rc2CBC (1 2 840 113549 3 2)
         : . . . . . . (RSADSI encryptionAlgorithm)
 490   14: . . . . . SEQUENCE {
 492    2: . . . . . . INTEGER 160
 496    8: . . . . . . OCTET STRING 3E EA 0E 12 37 A8 56 70                 
         : . . . . . . }

(Puede confirmar que RC2Version 160 (0xa0) coincide con el tamaño de clave de 40 bits (0x28) en la tabla EKB.)

Entonces, reuniéndolo todo: el algoritmo de cifrado S / MIME (RC2 40 bit CBC, offset 480), la clave RC2 (descifrada de blob en offset 203), RC2 IV (no encriptada, offset 496) y carga útil encriptada (compensación 506):

$ openssl enc -d -rc2-40-cbc -in email.bin -out email.txt -K 92F6EB53B1 -iv 3EEA0E1237A85670

y email.txt deben ser lo que estás buscando.

Consejos:

  • asegúrate de no usar una versión antigua de xxd , puede dañar los datos del hexágono de entrada
  • la estructura, los tamaños y las compensaciones, por supuesto, variarán según el mensaje, las claves y el algoritmo
  • Encuentro que openssl enc -kfile ... no funciona, quédate con -K
  • openssl smime puede haber modificado su mensaje antes del cifrado ( CRLF requisitos )
  • berdump es una herramienta útil ya que su salida es más susceptible de procesamiento adicional. Dado que DER es un subconjunto de BER, puede apuntarlo directamente a un archivo PKCS # 7 DER
respondido por el mr.spuratic 11.11.2013 - 19:32
fuente
0

S / MIME utiliza PKCS7 . Probablemente tengas que escribir el código tú mismo.

Aquí hay un ejemplo de cómo hacerlo en C ++: enlace

Y este es un ejemplo para Java: enlace

    
respondido por el ceving 10.11.2013 - 00:15
fuente

Lea otras preguntas en las etiquetas