= Pruebas con la librería "crypto" = [[br]] 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.