1
votes

im working with a web application for some client who needs sign some documents other company give him 2 files - file1.key - file2.cer if im understand thus files are encrypted with a password so the user needs his password

the company give me some example in php and say i need get the private key with thus commands

-convert *.key a *.pem: openssl pkcs8 -inform DER -in llave.key -out llave.key.pem -passin pass:contrasenia

-Conver *.cer to *.pem: openssl pkcs8 -inform DER -in llave.key -out llave.key.pem -passin pass:contrasenia

but for the end user i can't request him "run this command" the end user need to indicate his password

the company give me some code in php

$private_file="c:/firma/llave_carlos.key.pem";
$public_file="c:/firma/cert_carlos.cer.pem";
$private_key = openssl_get_privatekey(file_get_contents($private_file));
exito = openssl_sign($cadena_original,$Firma,$private_key, OPENSSL_ALGO_SHA256);
openssl_free_key($private_key);
$public_key = openssl_pkey_get_public(file_get_contents($public_file));
$PubData = openssl_pkey_get_details($public_key);
$result = openssl_verify($cadena_original, $Firma, $public_key, "sha256WithRSAEncryption");

but im working with Nodejs searching in google i found the npm package node-openssl-cert but until now i can't found a similar method to php "openssl_get_privatekey"

im thinks the solution is with the crypto module from node

const crypto = require('crypto');

const { privateKey, publicKey } = crypto.generateKeyPairSync('ec', {
  namedCurve: 'sect239k1'
});

const sign = crypto.createSign('SHA256');
sign.write('some data to sign');
sign.end();
const signature = sign.sign(privateKey, 'hex');

const verify = crypto.createVerify('SHA256');
verify.write('some data to sign');
verify.end();
console.log(verify.verify(publicKey, signature));

but my problem its this line

const { privateKey, publicKey } = crypto.generateKeyPairSync('ec', {
  namedCurve: 'sect239k1'
});

the "privatekey" and "publickey" should come from the files

thanks for the support and sorry for my english idont speak

1

1 Answers

1
votes

Let me guess: you're building a CFDI 3.3 and trying to sign the original string to get the digital sign. I ran into the same problem, searched a lot, downloaded lots of Node libraries, and your progress really helped me, so I could integrate a solution using only crypto library, here it is:

Firstful, be sure that the original string is ok (that was my first issue, the original string was wrong), you can use this tool: https://solucionfactible.com/sfic/capitulos/timbrado/cadena_original.jsp#herramientaCO

Once you checked the original string you need to sign the original string with SHA256, here you can find a function I coded for that:

const privateKey   = "./EKU9003173C9.key.pem" //Note that I converted the .key to .key.pem
const firmarCadena = cadena => {
    let prvKey = fs.readFileSync( privateKey )
    var signerObject = crypto.createSign("SHA256")
    signerObject.update( cadena )
    let signature = signerObject.sign( prvKey, "base64" )
    return signature
}

You can also check this tool, so you can compare between the values you are getting and the ones which must be. It generates the original string and digital sign with a .xml, .key and private key password: https://solucionfactible.com/sfic/capitulos/timbrado/sello.jsp#herramientaSello

Finally, you can verify your digital sign here in section "Verificador de sello digital (verificador de firma)": https://solucionfactible.com/sfic/capitulos/timbrado/sello.jsp#herramientaSello

I need to say that I'm using Node 10.x. It already has a Crypto built-in library.