Estoy interesado en saber cómo y dónde OpenSSL inserta la sal generada en los datos cifrados AES. ¿Por qué? Estoy cifrando datos en clases de Java y necesito garantizar que puedo usar OpenSSL para descifrarlos.
Por ejemplo, digamos que tengo esta cadena base64 cifrada, generada con la frase de contraseña "abc"
:
U2FsdGVkX1+tfvgUkjErP6j2kUAVwWZzNlaAmTqhzTk=
# generated with "openssl enc -aes-256-cbc -a"
Para descifrarlo podemos usar:
echo U2FsdGVkX1+tfvgUkjErP6j2kUAVwWZzNlaAmTqhzTk= | openssl enc -d -a -aes-256-cbc -p
# enc -d
# decryption
# -a
# input is base64
# -aes-256-cbc
# the aes algorithm used in encryption
# -p
# print salt, key and iv params
Ejecutar esto usando la frase de contraseña "abc"
resultará en:
salt=AD7EF81492312B3F
key=DEC1F5A1E5EAAA7DD539BBCFCEB1BB18868B974186ED056C27046ADD3A752C8B
iv =95A770DE9E0130E77C8E5D796D1B4EF5
Polaco
Ahora, sabemos que para que AES descifre los datos necesita la clave y el Vector de inicialización.
En el caso de OpenSSL, el manual dice que la clave se genera a partir de la frase de contraseña y una sal , y el Vector de inicialización se deriva de la propia clave (si no se especifica manualmente). Eso significa que los datos generados no necesitan tener el IV en él, pero sí que tienen la sal, o la clave para el descifrado nunca se generará correctamente.
Entonces, el punto es, ¿dónde está la sal y cómo se inserta en los datos resultantes? Haciendo un análisis básico de los datos generados (descodificando desde base64 y generando los valores hexadecimales) podemos ver que la sal no se anexa o anexa a los datos resultantes, pero de alguna manera está ahí:
# salt: AD7EF81492312B3F
echo U2FsdGVkX1+tfvgUkjErP6j2kUAVwWZzNlaAmTqhzTk= | openssl enc -d -base64 | od -x
0000000 6153 746c 6465 5f5f 7ead 14f8 3192 3f2b
0000020 f6a8 4091 c115 7366 5636 9980 a13a 39cd
0000040
Puede ver que la sal "AD7E..."
no está presente directamente en los datos cifrados. Parece que ha ocurrido alguna transformación.
Parece que la sal se cambia par a par y se inserta en los datos, comenzando en el byte # 9. ¿Es esta una práctica común o algo que solo implementa OpenSSL?
# salt: AD7E F814 9231 2B3F
# switch pair by pair: 7EAD 14F8 3192 3F2B
# data: 6153 746c 6465 5f5f 7ead 14f8 3192 3f2b f6a8 4091 c115 7366 5636 9980 a13a 39cd
Editar
Como declaró Thomas Pornin, el problema aquí es que od -x
genera los datos en bruto. Como mi computadora es x86_64, los datos están en little endian y la sal parece "intercambiada". Había olvidado que endianness es complicado. Ahora siempre recordaré usar od -t x1
De todos modos, todavía estoy interesado en saber si insertar la sal en el noveno byte es una práctica común o una implementación específica de OpenSSL. También noté que los primeros bytes son los caracteres Salted__