597 | | Para la librería javaScript Crypto: se necesita una función que me permita firmar el hash recibido desde el servicio Murachí. |
598 | | 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'' |
599 | | |
600 | | {{{ |
601 | | function importCryptoKeyPkcs8(privateKey,extractable) |
602 | | { |
603 | | var privateKeyInfoDerBuff = privateKeyToPkcs8(privateKey); |
604 | | //Importa la clave en la webcrypto |
605 | | return crypto.subtle.importKey( |
606 | | 'pkcs8', |
607 | | privateKeyInfoDerBuff, |
608 | | { name: "RSASSA-PKCS1-v1_5", hash:{name:"SHA-256"}}, |
609 | | extractable, |
610 | | ["sign"]); |
611 | | } |
612 | | }}} |
613 | | |
614 | | donde la variable ''privateKey'' corresponde a la variable donde se almaceno la clave privada en la función ''getCertificate()'' |
615 | | La función ''privateKeyToPkcs8'' transforma la clave priva en formato ''pkcs8'' |
616 | | |
617 | | {{{ |
618 | | function privateKeyToPkcs8(privateKey) |
619 | | { |
620 | | var rsaPrivateKey = forge.pki.privateKeyToAsn1(privateKey); |
621 | | var privateKeyInfo = forge.pki.wrapRsaPrivateKey(rsaPrivateKey); |
622 | | var privateKeyInfoDer = forge.asn1.toDer(privateKeyInfo).getBytes(); |
623 | | var privateKeyInfoDerBuff = stringToArrayBuffer(privateKeyInfoDer); |
624 | | return privateKeyInfoDerBuff; |
625 | | } |
626 | | }}} |
627 | | |
628 | | 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 |
629 | | |
630 | | {{{ |
631 | | function SingHash() |
632 | | { |
633 | | console.log("*.... SingFile ....*"); |
634 | | importCryptoKeyPkcs8(privateKey,true).then(function(cryptoKey) |
635 | | { |
636 | | var digestToSign = forge.util.decode64(digestToSignB64); |
637 | | var digestToSignBuf = stringToArrayBuffer(digestToSign); |
638 | | crypto.subtle.sign( |
639 | | {name: "RSASSA-PKCS1-v1_5"}, |
640 | | cryptoKey, |
641 | | digestToSignBuf) |
642 | | .then(function(signature){ |
643 | | sign = arrayBufferToString(signature); |
644 | | signatureB64 = forge.util.encode64(sign); |
645 | | signatureHEX = forge.util.bytesToHex(signatureB64); |
646 | | signatureBytesHex = forge.util.bytesToHex(signature); //hash firmado |
647 | | }); |
648 | | }); |
649 | | } |
650 | | }}} |
651 | | |
652 | | 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. |
653 | | Opciones de configuración de la petición $.ajax: para el envío del hash |
654 | | * '''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". |
655 | | * '''type:''' Esatblece el tipo de petición, para esta sección vamos a utilizar "POST". |
656 | | * '''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”. |
657 | | * ''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}). |
658 | | * ''contentType:'' Establece el tipo de codificación que se va a utilizar, para esta sección es "application/json". |
659 | | * '''xhrFields''' y '''headers:''' ya indicado al principio de esta sección. |
660 | | |
661 | | Código de la función javaScript "SignFilePDF()" sección 3: |
662 | | |
663 | | {{{ |
664 | | document.getElementById("seccion2").innerHTML = responseString; |
665 | | var json_x = data; |
666 | | var hash = json_x['hash']; |
667 | | alert("hash recibido del servidor "+hash); |
668 | | var hashtype = "SHA-256"; |
669 | | var lang = "eng"; |
670 | | SingHash() |
671 | | signature = signatureBytesHex; |
672 | | $.ajax({ |
673 | | type: 'POST', |
674 | | contentType: 'application/json', |
675 | | url:"https://murachi.cenditel.gob.ve/Murachi/0.1/archivos/pdfs/resenas", |
676 | | dataType: 'json', |
677 | | data: JSON.stringify({"signature":signature}), |
678 | | xhrFields: {withCredentials: true}, |
679 | | headers: {"Authorization":"Basic YWRtaW46YWRtaW4="}, |
680 | | success: function(data, textStatus, jqXHR){ |
681 | | var responseString = JSON.stringify(data); |
682 | | document.getElementById("seccion3").innerHTML = responseString; |
683 | | alert('Archivo firmado correctamente: ' + data['signedFileId']); |
684 | | document.getElementById("seccion4").innerHTML = "Descargar archivo firmado: https://murachi.cenditel.gob.ve/Murachi/0.1/archivos/descargas/" + data['signedFileId']; |
685 | | } // repuesta del ajax 3 |
686 | | }) //ajax 3 |
687 | | |
688 | | }}} |
689 | | |
690 | | 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. |
| 597 | * [wiki:actividades_2018_pruebas_cer_dig_lib_crypto Pruebas con la librería "crypto"] |
| 598 | |
| 599 | * [wiki:actividades_2018_pruebas_cer_dig_lib_hwcrypto Pruebas con la librería "hwcrypto"] |
| 600 | |
| 601 | * [wiki:actividades_2018_pruebas_cer_dig_lib_forge Pruebas con la librería "forge"] |