2012-01-05 163 views
19

Necesito encriptar una cadena usando una clave pública (archivo pem) y luego firmarla usando una clave privada (también una pem).Cifrado de datos con clave pública en node.js

Estoy cargando los archivos PEM bien:

publicCert = fs.readFileSync(publicCertFile).toString(); 

pero después de horas de fregar Google Me parece que no puede encontrar una manera de cifrar los datos utilizando la clave pública. En php simplemente llamo openssl_public_encrypt, pero no veo ninguna función correspondiente en el nodo o en ningún módulo.

Si alguien tiene alguna sugerencia, hágamelo saber.

Respuesta

60

No Biblioteca amigos necesarias,

Introduzca crypto

aquí hay un pequeño módulo de janky se puede utilizar para cifrar/descifrar cadenas con claves RSA:

var crypto = require("crypto"); 
var path = require("path"); 
var fs = require("fs"); 

var encryptStringWithRsaPublicKey = function(toEncrypt, relativeOrAbsolutePathToPublicKey) { 
    var absolutePath = path.resolve(relativeOrAbsolutePathToPublicKey); 
    var publicKey = fs.readFileSync(absolutePath, "utf8"); 
    var buffer = new Buffer(toEncrypt); 
    var encrypted = crypto.publicEncrypt(publicKey, buffer); 
    return encrypted.toString("base64"); 
}; 

var decryptStringWithRsaPrivateKey = function(toDecrypt, relativeOrAbsolutePathtoPrivateKey) { 
    var absolutePath = path.resolve(relativeOrAbsolutePathtoPrivateKey); 
    var privateKey = fs.readFileSync(absolutePath, "utf8"); 
    var buffer = new Buffer(toDecrypt, "base64"); 
    var decrypted = crypto.privateDecrypt(privateKey, buffer); 
    return decrypted.toString("utf8"); 
}; 

module.exports = { 
    encryptStringWithRsaPublicKey: encryptStringWithRsaPublicKey, 
    decryptStringWithRsaPrivateKey: decryptStringWithRsaPrivateKey 
} 

recomendaría no usar métodos fs síncronos cuando sea posible, y se podía utilizar promete hacer esto mejor, pero para un uso sencillo casos este es el enfoque que he visto funcionar y tomaría

+1

Esto funciona para mí ... es mejor ser nativo ... – ATOzTOA

+0

Gracias por editar @uzyn –

+0

Gracias por la solución @JacobMcKay Me salvó un par de horas. – uzyn

7

¿Qué tal este node-rsa module? Aquí hay un enlace al test.js file that demonstrates usage.

+1

Tal vez deba familiarizarme más con el cifrado RSA. Leí los documentos en crypto una docena de veces tratando de ver cómo hacer lo que necesitaba, pero no encontré nada. Está diciendo que createCipheriv() hará lo que necesito, pero ni siquiera sé qué es "iv". Supongo que es porque está más abstraído en PHP y otros lenguajes. Jugaré con esa función y veré si puedo hacer que funcione. – Clint

+1

Después de leer más sobre createCipheriv parece que no es un cifrado asimétrico (cifrado de clave pública/privada). No creo que cubra mis necesidades. Crypto tiene la capacidad de firmar una cadena encriptada con una clave privada, lo que me hace preguntarme por qué no puedo encriptar usando una clave pública. Parece extraño, o de lo contrario me falta algo por completo. – Clint

+0

iv es una vectior de inicialización. http://en.wikipedia.org/wiki/Initialization_vector –

8

El módulo de descifrado y descifrado público/privado actualizado es URSA. El módulo node-rsa está desactualizado.

Este módulo Node proporciona un conjunto bastante completo de contenedores para el público RSA/funcionalidad de cifrado de clave privada de OpenSSL.

NPM instalar ursa

Ver: https://github.com/Obvious/ursa

+3

Ursa no se ha mantenido durante bastante tiempo. Estas implementaciones más recientes pueden ser útiles: https://github.com/tracker1/cryptico-js y https://github.com/rzcoder/node-rsa –

3

TL; DR: Osa es su mejor apuesta. Es realmente funky que esto no viene de manera estándar con el nodo crypto.

Todas las demás soluciones que encontré o no funcionan en Windows o no son realmente bibliotecas de cifrado. Ursa, recomendado por Louie, parece ser la mejor opción. Si no te importan las ventanas, estás aún más dorado. Nota sobre Ursa, tuve que instalar Open SSL junto con algo llamado "Redistribuibles de Visual C++ 2008" para que la instalación de npm funcione. Obtener esa basura aquí: http://slproweb.com/products/Win32OpenSSL.html

El desglose:

Esto es literalmente todo lo que pude encontrar.

+1

node-rsa ya no dependen de node-waf. Es compatible con el navegador. – 131

2

Esto no es compatible de forma nativa por la versión del nodo v0.11.13 o por debajo, pero parece que la próxima versión del nodo (a.k.a v0.12) lo admitirá.

Aquí está la clave: https://github.com/joyent/node/blob/v0.12/lib/crypto.js#L358

ver crypto.publicEncrypt y crypto.privateDecrypt

Aquí está la documentación de futuro para este https://github.com/joyent/node/blob/7c0419730b237dbfa0ec4e6fb33a99ff01825a8f/doc/api/crypto.markdown#cryptopublicencryptpublic_key-buffer

Cuestiones relacionadas