2012-10-05 19 views
7

Así que estoy portando una biblioteca de ruby ​​a node.js, y necesito crear una firma PKCS7.¿Cómo hacer esto PKCS7 firmando en node.js?

Esto es lo que la lib rubí está haciendo:

p12_certificate = OpenSSL::PKCS12::new(File.read('some-path.c12'), self.certificate_password) 
x509_certificate = OpenSSL::X509::Certificate.new(File.read('some-other-path.pem')) 


flag = OpenSSL::PKCS7::BINARY|OpenSSL::PKCS7::DETACHED 
signed = OpenSSL::PKCS7::sign(p12_certificate.certificate, p12_certificate.key, File.read('some-manifest'), [x509_certificate], flag) 

¿cómo iba a lograr lo mismo en el nodo? Lo que supongo que sería algo así como:

crypto.createCredentials({ 
    pfx : fs.readFileSync('some-cert.p12'), 
    passphrase : this.certificate_password, 
    cert : fs.readFileSync('some-path.pem','some-encoding'), 
}) 

Preguntas:

  • ¿Es esta la manera correcta de hacer esto?
  • ¿Debo especificar una clave, lista de ca, crl list o lista de cifrados?
  • ¿qué codificación debo usar para leer el certificado?
  • lo que es el nodo equivalente de establecer signed
  • línea de lo que es el nodo equivalente de signed.to_der
+0

Está escribiendo una biblioteca de libretas de Apple. He luchado tratando de descubrir lo mismo. –

+0

@ChrisF - entonces, ¿te rindiste, o qué? Sé que node puede lograr esto, al menos usando el firmante de muestra de apple escrito en C; sin embargo, me gustaría evitar introducir una dependencia compilada. – Jesse

+0

@Jesse ¿Y usted? Todavía estancado en esto, estoy enfrentando el mismo desafío para un servidor MDM de nodo, ¡pero estoy atrapado antes! cf. http://stackoverflow.com/questions/12956995/pkcs7-data-payload-unpacking-with-nodejs – Olivier

Respuesta

0

Verify PKCS#7 (PEM) signature/unpack data in node.js

no puedo hacer ningún comentario más que el vínculo, pero espero que esto puede ayudarle a empezar. Esto es solo verificar la firma, sin embargo, estoy seguro de que puede realizar una ingeniería inversa para crear una.

0

No hay forma de hacerlo de forma nativa en el nodo o iojs en este momento, lo mejor que puede hacer es ejecutar un comando de ejecución usando smime module para un ejemplo.

1

este código puede ayudarlo. Está diseñado para PKCS7, pero puede modificar la línea de comando de openssl como lo desee.

var util = require('util'); 
var spawn = require('child_process').spawn; 
var Promise = require('promise'); 

// Expose methods. 
exports.sign = sign; 

/** 
* Sign a file. 
* 
* @param {object} options Options 
* @param {stream.Readable} options.content Content stream 
* @param {string} options.key Key path 
* @param {string} options.cert Cert path 
* @param {string} [options.password] Key password 
* @param {function} [cb] Optional callback 
* @returns {object} result Result 
* @returns {string} result.pem Pem signature 
* @returns {string} result.der Der signature 
* @returns {string} result.stdout Strict stdout 
* @returns {string} result.stderr Strict stderr 
* @returns {ChildProcess} result.child Child process 
*/ 

function sign(options, cb) { 
    return new Promise(function (resolve, reject) { 
     options = options || {}; 

     if (!options.content) 
      throw new Error('Invalid content.'); 

     if (!options.key) 
      throw new Error('Invalid key.'); 

     if (!options.cert) 
      throw new Error('Invalid certificate.'); 

     var command = util.format(
      'openssl smime -sign -text -signer %s -inkey %s -outform DER -nodetach', 
      options.cert, 
      options.key 
     ); 

     if (options.password) 
      command += util.format(' -passin pass:%s', options.password); 

     var args = command.split(' '); 
     var child = spawn(args[0], args.splice(1)); 

     var der = []; 

     child.stdout.on('data', function (chunk) { 
      der.push(chunk); 
     }); 

     child.on('close', function (code) { 
      if (code !== 0) 
       reject(new Error('Process failed.')); 
      else 
       resolve({ 
        child: child, 
        der: Buffer.concat(der) 
       }); 
     }); 

     options.content.pipe(child.stdin); 
    }) 
     .nodeify(cb); 
} 

Mi archivo se llama: signHelper. Este es el código para llamarlo:

signHelper.sign({ 
      content: s, 
      key: path.join(__dirname, '../certs/test/' + "keyfile.key")//, 
      cert: path.join(__dirname, '../certs/test/' + "certfile.crt"), 
      password: 'password' 
     }).catch(function (err) { 
      logger.error("Error signing: " + err.stack); 
      callback(err); 
     }).then(function (result) { 
      logger.info("signTicket ++++++++++++"); 
      callback(null, result.der); //result.der is the signed certificate 
     }); 

Sólo hay que entender cómo hacer lo que necesita con OpenSSL. Espero que funcione para usted.