wiki:actividades_2018_pruebas_cer_dig_lib_crypto

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.