Version 1 (modified by aosorio, 6 years ago) (diff) |
---|
Pruebas con la librería "crypto"
Para la librería javaScript Crypto: se necesita una función que me permita firmar el hash recibido desde el servicio Murachí. Para este caso, como obtuvimos el certificado del firmarte y la clave privada con la librería forge en la función getCertificate, necesitamos importar la clave privada para que pueda ser utilizada por la librería Crypto
function importCryptoKeyPkcs8(privateKey,extractable) { var privateKeyInfoDerBuff = privateKeyToPkcs8(privateKey); //Importa la clave en la webcrypto return crypto.subtle.importKey( 'pkcs8', privateKeyInfoDerBuff, { name: "RSASSA-PKCS1-v1_5", hash:{name:"SHA-256"}}, extractable, ["sign"]); }
donde la variable privateKey corresponde a la variable donde se almaceno la clave privada en la función getCertificate() La función privateKeyToPkcs8 transforma la clave priva en formato pkcs8
function privateKeyToPkcs8(privateKey) { var rsaPrivateKey = forge.pki.privateKeyToAsn1(privateKey); var privateKeyInfo = forge.pki.wrapRsaPrivateKey(rsaPrivateKey); var privateKeyInfoDer = forge.asn1.toDer(privateKeyInfo).getBytes(); var privateKeyInfoDerBuff = stringToArrayBuffer(privateKeyInfoDer); return privateKeyInfoDerBuff; }
Definida estas funciones se presenta la función encargada de realizar la firma del hash usando la libreria crypto, para la misma se necesita la clave privada y el hash a firmar. Independientemente de la función que se utilice para firma el hash. Independientemente de la librería que se use para firmar el hash se va a utilizar la siguiente configuración de la petición $.ajax para el envió del hash
function SingHash() { console.log("*.... SingFile ....*"); importCryptoKeyPkcs8(privateKey,true).then(function(cryptoKey) { var digestToSign = forge.util.decode64(digestToSignB64); var digestToSignBuf = stringToArrayBuffer(digestToSign); crypto.subtle.sign( {name: "RSASSA-PKCS1-v1_5"}, cryptoKey, digestToSignBuf) .then(function(signature){ sign = arrayBufferToString(signature); signatureB64 = forge.util.encode64(sign); signatureHEX = forge.util.bytesToHex(signatureB64); signatureBytesHex = forge.util.bytesToHex(signature); //hash firmado }); }); }
Una ves firmado el hash con el certificado firmante (almacenado en la variable signatureBytesHex) se procede a enviar al servicio Murachí para completar la firma, para este proceso de envío usando el metodo $ajax. Opciones de configuración de la petición $.ajax: para el envío del hash
- url: Establece la URL en donde se realiza la petición, para esta sección es "https://murachi.cenditel.gob.ve/Murachi/0.1/archivos/pdfs/resenas".
- type: Esatblece el tipo de petición, para esta sección vamos a utilizar "POST".
- dataType: Establece el formato de la respuesta que es permitido, si el servidor devuelve información con un formato diferente al especificado el código fallará. Para esta sección se establece “json”.
- data: Establece la información que se enviará al servidor. Para esta sección se enviá el hash que se obtiene de la siguiente manera: JSON.stringify({"signature":signature.hex}).
- contentType: Establece el tipo de codificación que se va a utilizar, para esta sección es "application/json".
- xhrFields y headers: ya indicado al principio de esta sección.
Código de la función javaScript "SignFilePDF()" sección 3:
document.getElementById("seccion2").innerHTML = responseString; var json_x = data; var hash = json_x['hash']; alert("hash recibido del servidor "+hash); var hashtype = "SHA-256"; var lang = "eng"; SingHash() signature = signatureBytesHex; $.ajax({ type: 'POST', contentType: 'application/json', url:"https://murachi.cenditel.gob.ve/Murachi/0.1/archivos/pdfs/resenas", dataType: 'json', data: JSON.stringify({"signature":signature}), xhrFields: {withCredentials: true}, headers: {"Authorization":"Basic YWRtaW46YWRtaW4="}, success: function(data, textStatus, jqXHR){ var responseString = JSON.stringify(data); document.getElementById("seccion3").innerHTML = responseString; alert('Archivo firmado correctamente: ' + data['signedFileId']); document.getElementById("seccion4").innerHTML = "Descargar archivo firmado: https://murachi.cenditel.gob.ve/Murachi/0.1/archivos/descargas/" + data['signedFileId']; } // repuesta del ajax 3 }) //ajax 3
Si la petición tiene éxito la repuesta de esta sección se procesa a través de la función success: donde se le pase tres parámetros, data: que corresponde al resultado de la petición formateado según el valor del parámetro dataType (respuesta del servidor), textStatus: que corresponde a una cadena que describe el estado y jpXHR: que es un objeto que permite ejecutar varias funciones.