2012-08-31 12 views
16

tengo los siguientes datos cifrada:¿Qué pasa con el descifrado crypto de nodejs?

U2FsdGVkX1+21O5RB08bavFTq7Yq/gChmXrO3f00tvJaT55A5pPvqw0zFVnHSW1o

El pase para descifrar que es: password

(Es el ejemplo de gibberish-aes)

En la línea de comandos usando openssl:

echo "U2FsdGVkX1+21O5RB08bavFTq7Yq/gChmXrO3f00tvJaT55A5pPvqw0zFVnHSW1o" | openssl enc -d -aes-256-cbc -a -k password

La salida es:

Made with Gibberish\n

Con mi solicitud NodeJS:

var decipher = crypto.createDecipher('aes-256-cbc', "password"); 
    var dec = decipher.update("U2FsdGVkX1+21O5RB08bavFTq7Yq/gChmXrO3f00tvJaT55A5pPvqw0zFVnHSW1o", 
    'base64', 'utf8'); 
    dec += decipher.final('utf8'); 

tengo el siguiente error en la línea de TypeError: DecipherFinal faildecipher.final.

¿Echo de menos algo? Gracias.

+1

Gran pregunta. Descubrí que openssl usa una sal cada vez, por lo que necesitas un interruptor '-nosalt'. Sin sal, utiliza la misma IV y la clave derivada cada vez, puede ver que proporcionan un conmutador '-p'. Luego puede hacer 'createDecipheriv (data, key, iv)' en el nodo. Pero no decodifica el texto correctamente de todos modos. Así que estoy atrapado también. –

+0

@owlstead He usado ** clave ** y ** iv ** directamente, ¿esto usa ** PBKDF2 **?http://pastebin.com/uhxTRn9T aquí están mi código y resultados. ¿Qué está mal? –

+0

He buscado en el código y debería usar la derivación de la clave openssl sin sal. No estoy seguro acerca de la IV. Sé que con Java tampoco puedo descifrar el resultado de openssl. La trama se complica. –

Respuesta

16

Los datos cifrados comienzan con una "magia" de 8 bytes que indica que hay una sal (la codificación ASCII de "Salted__"). Entonces los próximos 8 bytes son la sal. Ahora las malas noticias: Node.js no parece utilizar la sal para el método EVP_BytesToKey:

int key_len = EVP_BytesToKey(cipher, EVP_md5(), NULL, 
    (unsigned char*) key_buf, key_buf_len, 1, key, iv); 

Eso NULL es la sal.

Esto se ha verificado utilizando una aplicación de prueba Java (utilizando la sal correcta) - se devolvió la cadena de resultados.

Por favor, omita la sal con el interruptor OpenSSL -nosalt y vuelva a intentarlo.

[Ejemplo]

OpenSSL CLI:

openssl enc -aes-256-cbc -nosalt -a -k password 
owlstead 
Mh5yxIyZH+fSMTkSgkLa5w== 

NodeJS cripto:

var crypto=require('crypto') 
var cipher=crypto.createDecipher('aes-256-cbc', "password") 
var enc = cipher.update("Mh5yxIyZH+fSMTkSgkLa5w==", 'base64', 'utf8') 
enc += cipher.final('utf8') 

[EDICIÓN TARDE] Tenga en cuenta que el uso de derivación de clave secreta con una sal y de trabajo grande factor puede ser primordial para la seguridad. Será mejor que use una contraseña de entropía única y muy alta, de lo contrario, sus datos encriptados podrían estar en riesgo.


[EDIT realmente tarde] OpenSSL 1.1.0c changed the digest algorithm utiliza en algunos componentes internos. Anteriormente, se usaba MD5 y 1.1.0 cambiaba a SHA256. Tenga cuidado de que el cambio no lo afecte tanto en EVP_BytesToKey como en comandos como openssl enc.

+0

datos encriptados después de la decodificación Base64, obviamente. –

+0

Pero uso '-nosalt' como dije antes ... Sé sobre la firma mágica' Salted__' en los resultados de codificación de OpenSSL predeterminados. Mi ejemplo de pastebin contiene '-nosalt'. –

+0

Esa cadena 'U2FsdGVkX1 + 21O5RB08bavFTq7Yq/gChmXrO3f00tvJaT55A5pPvqw0zFVnHSW1o' contiene sin embargo la sal. De lo contrario, puede ver fácilmente que es demasiado grande (incluso si no solo decodifica la base64 y ve los primeros 8 bytes codificados en ASCII). –