Changes between Version 9 and Version 10 of actividades_2018_pruebas


Ignore:
Timestamp:
May 30, 2018, 5:03:18 PM (6 years ago)
Author:
aosorio
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • actividades_2018_pruebas

    v9 v10  
    11= Adecuación del portal de Murachí para firmar y verificar documentos firmados electrónicamente usando certificados digitales =
     2
     3[[br]]
    24
    35Los archivos .p12 o .pfx es una formar de almacenar los certificados digitales juntos con la clave privada, estos archivos contiene información necesario para que el usuario pueda realizar firmas electrónicas.
     
    1618Como el servicio de firma electrónica se realiza en varios pasos vamos a dividir el ejercicio en secciones.
    1719
    18 '''Sección 1: Subir documento pdf:'''
    19 
    20 En la primera sección se envía al sistema Murachí el archivo pdf que se va a firmar. Entonces para esta sección se requiere de un formulario que permita tomar del sistema de archivo documentos pdf y luego enviarlo con el método ''$.ajax usando el recurso /Murachi/0.1/archivos/''
    21 '''
    22 Característica del formulario HTML'''
     20== Sección 1: Subir documento pdf ==
     21
     22En la primera sección se envía al sistema Murachí el archivo pdf que se va a firmar. Entonces para esta sección se requiere de un formulario que permita tomar del sistema de archivo documentos pdf y luego enviarlo con el método ''$.ajax usando el recurso /Murachi/0.1/archivos/'' '''Característica del formulario HTML'''
     23
     24[[br]]
    2325Control:
    24 
    25  * Botón de envío (Submit button)
    26  * Botón de reinicializando (Reset button)
    27  * Selección de fichero (file select)
     26* Botón de envío (Submit button)
     27* Botón de reinicializando (Reset button)
     28* Selección de fichero (file select)
    2829
    2930Atributos:
    3031 
    31  * action: función de javaScript que procesa el formulario para esta actividad la función es “SignFilePDF()”
    32  * enctype: este atributo específica el tipo de contenido que sera usado para enviar los datos al servidor, para esta actividad se utilizará “multipart/form-data”
    33 
    34 '''Código del formulario HTML:'''
    35 
    36 {{{
    37 || <form enctype="multipart/form-data" method="post" id="firmar" name="SignFormat">[[BR]]
    38 
    39     <h2>Firmar electr&oacute;nica (PDF)</h2>[[BR]]
    40 
    41     <h3>Seleccione el archivo que va a firmar electr&oacute;nicamente</h2> [[BR]]
     32* action: función de javaScript que procesa el formulario para esta actividad la función es “SignFilePDF()”
     33* enctype: este atributo específica el tipo de contenido que sera usado para enviar los datos al servidor, para esta actividad se utilizará “multipart/form-data”
     34
     35'''Código del formulario HTML:'''
     36
     37{{{
     38<form enctype="multipart/form-data" method="post" id="firmar" name="SignFormat">
     39    <h2>Firmar electr&oacute;nica (PDF)</h2>
     40
     41    <h3>Seleccione el archivo que va a firmar electr&oacute;nicamente</h2>
    4242       
    4343    <br>
    44     <input id="file-sign" class="file" type="file" data-min-file-count="1" name="upload" accept=".pdf" >[[BR]]
     44    <input id="file-sign" class="file" type="file" data-min-file-count="1" name="upload" accept=".pdf" >
    4545
    4646    <br>
    47 </form>[[BR]]
    48 
    49 <button type="button" name="buttonsubmit3" id="buttonsubmit3" onclick="SignFilePDF();" class="btn btn-primary btn-lg">Firmar</button>[[BR]]
    50 
    51 <button type="reset" id="reset"  class="btn btn-default">Limpiar</button>[[BR]]
     47</form>
     48
     49<button type="button" name="buttonsubmit3" id="buttonsubmit3" onclick="SignFilePDF();" class="btn btn-primary btn-lg">Firmar</button>
     50
     51<button type="reset" id="reset"  class="btn btn-default">Limpiar</button>
    5252
    5353<br>
     
    7272{{{
    7373<div>
    74 
    75 <label for="pfx">Seleccione el archivo PFX / P12::</label><br>[[BR]]
    76 
    77 <input name="pfx" class="form-control" type="file" id="pfx" accept=".pfx,.p12" required /><br>[[BR]]
    78 
    79 <label for="pfxp">Ingrese la contraseña de clave privada:</label><br>[[BR]]
    80 
    81 <input name="pfxp" class="form-control" type="password" id="pfxp" /><br>[[BR]]
    82 
     74  <label for="pfx">Seleccione el archivo PFX / P12::</label><br>
     75
     76  <input name="pfx" class="form-control" type="file" id="pfx" accept=".pfx,.p12" required /><br>
     77
     78  <label for="pfxp">Ingrese la contraseña de clave privada:</label><br>
     79
     80  <input name="pfxp" class="form-control" type="password" id="pfxp" /><br>
    8381</div>
    8482}}}
     
    9391
    9492{{{
    95   function getCertificate(e)
    96         {
    97         console.log("*... getCertificate ...*");[[BR]]
    98 
    99         // Get PFX
    100         var fileInput = document.getElementById('pfx');[[BR]]
    101 
    102         var file = fileInput.files[0];[[BR]]
    103 
    104         // Read it
    105         var reader = new FileReader();[[BR]]
    106 
    107         reader.onload = function(e)  {
    108                 console.log("*.... cargo el archivo .p12 ....*");[[BR]]
    109 
    110                 var contents = e.target.result;[[BR]]
    111 
    112                 pkcs12Der = arrayBufferToString(contents);[[BR]]
    113 
    114                 pkcs12B64 = forge.util.encode64(pkcs12Der);[[BR]]
    115 
    116                 var pkcs12Asn1 = forge.asn1.fromDer(pkcs12Der);[[BR]]
    117 
    118                 var password = $('#pfxp').val();[[BR]]
    119 
    120                 pkcs12 = forge.pkcs12.pkcs12FromAsn1(pkcs12Asn1, false, password);[[BR]]
    121 
    122                 // load keys
    123                 for(var sci = 0; sci < pkcs12.safeContents.length; ++sci)
    124                         {[[BR]]
    125 
    126                         var safeContents = pkcs12.safeContents[sci];[[BR]]
    127 
    128                         for(var sbi = 0; sbi < safeContents.safeBags.length; ++sbi)
    129                                 {
    130                                 var safeBag = safeContents.safeBags[sbi];[[BR]]
    131 
    132                                 if(safeBag.type === forge.pki.oids.keyBag) [[BR]]
    133 
    134                                         {
    135                                         //Found plain private key
    136                                         privateKey = safeBag.key;[[BR]]
    137 
    138                                         }
    139                                 else
    140                                 if(safeBag.type === forge.pki.oids.pkcs8ShroudedKeyBag) [[BR]]
    141 
    142                                         {
    143                                         // found encrypted private key
    144                                         privateKey = safeBag.key;[[BR]]
    145 
    146                                         }
    147                                 else
    148                                 if(safeBag.type === forge.pki.oids.certBag) [[BR]]
    149 
    150                                         {
    151                                         // this bag has a certificate...
    152                                         certCount = certCount +1;       [[BR]]
    153 
    154 
    155                                         if(certP12bag == null) [[BR]]
    156 
    157                                                 {
    158                                                 certP12bag = safeBag.cert;[[BR]]
    159 
    160                                                 certpem = "" +  forge.pki.certificateToPem(certP12bag).toString();[[BR]]
    161 
    162                                                 certBytesHex = forge.util.bytesToHex(certpem);[[BR]]
    163 
    164                                                 }[[BR]]
    165 
    166                                         }       [[BR]]
    167 
    168                                 }[[BR]]
    169 
    170                         }[[BR]]
    171 
    172                 }[[BR]]
    173 
    174                 reader.readAsArrayBuffer(file);[[BR]]
    175 
    176         }[[BR]]
    177 
    178 }}}
    179 
    180 ----
     93function getCertificate(e)
     94  {
     95  console.log("*... getCertificate ...*");
     96
     97  // Get PFX
     98  var fileInput = document.getElementById('pfx');
     99
     100  var file = fileInput.files[0];
     101
     102  // Read it
     103  var reader = new FileReader();
     104
     105  reader.onload = function(e)  {
     106    console.log("*.... cargo el archivo .p12 ....*");
     107
     108    var contents = e.target.result;
     109
     110    pkcs12Der = arrayBufferToString(contents);
     111
     112    pkcs12B64 = forge.util.encode64(pkcs12Der);
     113
     114    var pkcs12Asn1 = forge.asn1.fromDer(pkcs12Der);
     115
     116    var password = $('#pfxp').val();
     117
     118    pkcs12 = forge.pkcs12.pkcs12FromAsn1(pkcs12Asn1, false, password);
     119
     120    // load keys
     121    for(var sci = 0; sci < pkcs12.safeContents.length; ++sci)
     122      {
     123
     124      var safeContents = pkcs12.safeContents[sci];
     125
     126      for(var sbi = 0; sbi < safeContents.safeBags.length; ++sbi)
     127        {
     128        var safeBag = safeContents.safeBags[sbi];
     129
     130        if(safeBag.type === forge.pki.oids.keyBag)
     131
     132          {
     133          //Found plain private key
     134          privateKey = safeBag.key;
     135
     136          }
     137        else
     138        if(safeBag.type === forge.pki.oids.pkcs8ShroudedKeyBag)
     139
     140          {
     141          // found encrypted private key
     142          privateKey = safeBag.key;
     143
     144          }
     145        else
     146        if(safeBag.type === forge.pki.oids.certBag)
     147
     148          {
     149          // this bag has a certificate...
     150          certCount = certCount +1;
     151
     152
     153          if(certP12bag == null)
     154
     155            {
     156            certP12bag = safeBag.cert;
     157
     158            certpem = "" +  forge.pki.certificateToPem(certP12bag).toString();
     159
     160            certBytesHex = forge.util.bytesToHex(certpem);
     161
     162            }
     163
     164          }
     165
     166        }
     167
     168      }
     169
     170    }
     171
     172    reader.readAsArrayBuffer(file);
     173
     174  }
     175
     176}}}
     177
    181178[[BR]]
    182179
     
    187184
    188185{{{
    189 
    190 function arrayBufferToString( buffer ) [[BR]]
    191 
    192         {
    193         var binary = '';[[BR]]
    194 
    195         var bytes = new Uint8Array( buffer );[[BR]]
    196 
    197         var len = bytes.byteLength;[[BR]]
    198 
    199         for (var i = 0; i < len; i++) [[BR]]
    200 
    201                 {
    202                 binary += String.fromCharCode( bytes[ i ] );[[BR]]
    203 
    204                 }
    205         return binary;[[BR]]
    206 
    207         }
     186function arrayBufferToString( buffer )
     187
     188  {
     189  var binary = ''
     190
     191  var bytes = new Uint8Array( buffer )
     192
     193  var len = bytes.byteLength
     194
     195  for (var i = 0; i < len; i++)
     196
     197    {
     198    binary += String.fromCharCode( bytes[ i ] )
     199
     200    }
     201  return binary
     202
     203  }
    208204}}}
    209205
     
    211207
    212208'''Función SignFilePDF() Sección 1. Subir documento pdf'''
    213 [[BR]]
    214209
    215210En esta sección la función procesa los datos del formulario. Vamos a cargar el archivo .p12 o .pfx y usando la función getCertificate(e), y se obtiene el archivo pdf seleccionado en el formulario a través del método document.getElementById("file-sign") donde “file-sign” corresponde al id del elemento input de tipo “file” del formulario. Luego se almacena en un objeto de tipo FormData que permite el envío del archivo al servidor usando el método $.ajax
     
    227222
    228223{{{
    229 function SignFilePDF() {[[BR]]
    230 
    231         //cargar el archivo .p12[[BR]]
    232 
    233         getCertificate();[[BR]]
    234 
    235         var fileInput = document.getElementById("file-sign");[[BR]]
    236 
    237         var list = fileInput.files;[[BR]]
    238 
    239         var form = $('firmar')[0];[[BR]]
    240 
    241         var data = new FormData();[[BR]]
    242 
    243         data.append('upload', $("#file-sign")[0].files[0]);[[BR]]
    244 
    245         $.ajax({   [[BR]]
     224function SignFilePDF() {
     225
     226  //cargar el archivo .p12
     227
     228      getCertificate();
     229
     230      var fileInput = document.getElementById("file-sign");
     231
     232      var list = fileInput.files;
     233
     234      var form = $('firmar')[0];
     235
     236      var data = new FormData();
     237
     238      data.append('upload', $("#file-sign")[0].files[0]);
     239
     240      $.ajax({   
    246241           
    247         url: "https://murachi.cenditel.gob.ve/Murachi/0.1/archivos",[[BR]]
    248 
    249         type: "post",[[BR]]
    250 
    251         dataType: "json",[[BR]]
    252 
    253         data: data,[[BR]]
    254 
    255         cache: false,[[BR]]
    256 
    257         contentType: false,[[BR]]
    258 
    259         processData: false,[[BR]]
    260 
    261         xhrFields: {withCredentials: true},[[BR]]
    262 
    263         headers: {"Authorization":"Basic YWRtaW46YWRtaW4="},[[BR]]
    264 
    265         success: function(response) {[[BR]]
    266 
    267             var responseString = JSON.stringify(response); [[BR]]
     242        url: "https://murachi.cenditel.gob.ve/Murachi/0.1/archivos",
     243
     244        type: "post",
     245
     246        dataType: "json",
     247
     248        data: data,
     249
     250        cache: false,
     251
     252        contentType: false,
     253
     254        processData: false,
     255
     256        xhrFields: {withCredentials: true},
     257
     258        headers: {"Authorization":"Basic YWRtaW46YWRtaW4="},
     259
     260        success: function(response) {
     261
     262            var responseString = JSON.stringify(response);
    268263                                     
    269             document.getElementById("seccion1").innerHTML = responseString;[[BR]]
    270 
    271         }[[BR]]
     264            document.getElementById("seccion1").innerHTML = responseString;
     265
     266        }
    272267
    273268)}
     
    278273La repuesta de esta sección se procesa por el método .done a través del argumento response donde podemos acceder al valor del JSON con la función JSON.stringify.
    279274
     275[[BR]]
    280276'''Código completo de la sección 1:'''
    281 [[BR]]
    282 
    283 ----
    284 {{{
    285 <!doctype html>[[BR]]
    286 
    287 <html>[[BR]]
    288 
    289 <head>[[BR]]
    290 
    291 <meta charset="utf-8">[[BR]]
    292 
    293     <title>Javascript firma p12 Demo</title>[[BR]]
    294 
    295     <script type="text/javascript" src="forge.min.js"></script>[[BR]]
    296 </head>[[BR]]
    297 
    298 <script>[[BR]]
     277
     278{{{
     279<!doctype html>
     280
     281<html>
     282
     283<head>
     284
     285<meta charset="utf-8">
     286
     287    <title>Javascript firma p12 Demo</title>
     288
     289    <script type="text/javascript" src="forge.min.js"></script>
     290</head>
     291
     292<script>
    299293
    300294//Funciones de conversión
    301295
    302 function arrayBufferToString( buffer ) [[BR]]
    303         {
    304         var binary = '';[[BR]]
    305         var bytes = new Uint8Array( buffer );[[BR]]
    306         var len = bytes.byteLength;[[BR]]
    307         for (var i = 0; i < len; i++) [[BR]]
    308                 {
    309                 binary += String.fromCharCode( bytes[ i ] );[[BR]]
    310                 }
    311         return binary;[[BR]]
    312         }
     296function arrayBufferToString( buffer )
     297  {
     298  var binary = '';
     299  var bytes = new Uint8Array( buffer );
     300  var len = bytes.byteLength;
     301  for (var i = 0; i < len; i++)
     302    {
     303    binary += String.fromCharCode( bytes[ i ] );
     304    }
     305  return binary;
     306  }
    313307
    314308//function que obtengo la clave privada y el certificado del archivo .p12
    315 function getCertificate(e)[[BR]]
    316         {
    317         // Get PFX[[BR]]
    318         var fileInput = document.getElementById('pfx');[[BR]]
    319         var file = fileInput.files[0];[[BR]]
    320         // Read it[[BR]]
    321         var reader = new FileReader();[[BR]]
    322         reader.onload = function(e)  {[[BR]]
    323                 var contents = e.target.result;[[BR]]
    324                 pkcs12Der = arrayBufferToString(contents);[[BR]]
    325                 pkcs12B64 = forge.util.encode64(pkcs12Der);[[BR]]
    326                 var pkcs12Asn1 = forge.asn1.fromDer(pkcs12Der);[[BR]]
    327                 var password = $('#pfxp').val();
    328                
    329                 pkcs12 = forge.pkcs12.pkcs12FromAsn1(pkcs12Asn1, false, password);[[BR]]
    330                 // load keys[[BR]]
    331                 for(var sci = 0; sci < pkcs12.safeContents.length; ++sci) [[BR]]
    332                         {[[BR]]
    333                         var safeContents = pkcs12.safeContents[sci];[[BR]]
    334                         for(var sbi = 0; sbi < safeContents.safeBags.length; ++sbi) [[BR]]
    335                                 {[[BR]]
    336                                 var safeBag = safeContents.safeBags[sbi];[[BR]]
    337                                 if(safeBag.type === forge.pki.oids.keyBag) [[BR]]
    338                                         {[[BR]]
    339                                         //Found plain private key[[BR]]
    340                                         privateKey = safeBag.key;[[BR]]
    341                                         } [[BR]]
    342                                 else [[BR]]
    343                                 if(safeBag.type === forge.pki.oids.pkcs8ShroudedKeyBag) [[BR]]
    344                                         {[[BR]]
    345                                         // found encrypted private key[[BR]]
    346                                         privateKey = safeBag.key;[[BR]]
    347                                         } [[BR]]
    348                                 else [[BR]]
    349                                 if(safeBag.type === forge.pki.oids.certBag) [[BR]]
    350                                         {[[BR]]
    351                                         // this bag has a certificate...[[BR]]
    352                                         certCount = certCount +1;       [[BR]]                                 
    353                                         console.log("GET_CERTIFICATE___"+ certCount + "...certBag Ok");  [[BR]]
    354 
    355                                         if(certP12bag == null) [[BR]]
    356                                                 { [[BR]]
    357                                                 certP12bag = safeBag.cert; [[BR]]
    358                                                 certpem = "" +  forge.pki.certificateToPem(certP12bag).toString(); [[BR]]
    359                                                 certBytesHex = forge.util.bytesToHex(certpem); [[BR]]
    360                                                 } [[BR]]
    361                                         }       [[BR]]
    362                                 }  [[BR]]
    363                         } [[BR]]
    364                 } [[BR]]
    365                 reader.readAsArrayBuffer(file); [[BR]]
    366         } [[BR]]
    367 
    368 //funcion que ejecuta el proceso de firma electrónica usando el servicio Murachí [[BR]]
    369 function SignFilePDF() { [[BR]]
    370         //cargar el archivo .p12 [[BR]]
    371         getCertificate(); [[BR]]
    372     var fileInput = document.getElementById("file-sign"); [[BR]]
    373     var list = fileInput.files; [[BR]]
    374     var form = $('firmar')[0]; [[BR]]
    375     var data = new FormData(); [[BR]]
    376     data.append('upload', $("#file-sign")[0].files[0]); [[BR]]
    377     $.ajax({               [[BR]]
    378         url: "https://murachi.cenditel.gob.ve/Murachi/0.1/archivos", [[BR]]
    379         type: "post", [[BR]]
    380         dataType: "json", [[BR]]
    381         data: data, [[BR]]
    382         cache: false, [[BR]]
    383         contentType: false, [[BR]]
    384         processData: false,[[BR]]
    385         xhrFields: {withCredentials: true},[[BR]]
    386         headers: {"Authorization":"Basic YWRtaW46YWRtaW4="},[[BR]]
    387         success: function(response) { [[BR]]
    388             var responseString = JSON.stringify(response);                                      [[BR]]
    389             document.getElementById("seccion1").innerHTML = responseString;[[BR]]
    390            }[[BR]]
    391     )}[[BR]]
     309function getCertificate(e)
     310  {
     311  // Get PFX
     312  var fileInput = document.getElementById('pfx');
     313  var file = fileInput.files[0];
     314  // Read it
     315  var reader = new FileReader();
     316  reader.onload = function(e)  {
     317    var contents = e.target.result;
     318    pkcs12Der = arrayBufferToString(contents);
     319    pkcs12B64 = forge.util.encode64(pkcs12Der);
     320    var pkcs12Asn1 = forge.asn1.fromDer(pkcs12Der);
     321    var password = $('#pfxp').val();
     322   
     323    pkcs12 = forge.pkcs12.pkcs12FromAsn1(pkcs12Asn1, false, password);
     324    // load keys
     325    for(var sci = 0; sci < pkcs12.safeContents.length; ++sci)
     326      {
     327      var safeContents = pkcs12.safeContents[sci];
     328      for(var sbi = 0; sbi < safeContents.safeBags.length; ++sbi)
     329        {
     330        var safeBag = safeContents.safeBags[sbi];
     331        if(safeBag.type === forge.pki.oids.keyBag)
     332          {
     333          //Found plain private key
     334          privateKey = safeBag.key;
     335          }
     336        else
     337        if(safeBag.type === forge.pki.oids.pkcs8ShroudedKeyBag)
     338          {
     339          // found encrypted private key
     340          privateKey = safeBag.key;
     341          }
     342        else
     343        if(safeBag.type === forge.pki.oids.certBag)
     344          {
     345          // this bag has a certificate...
     346          certCount = certCount +1;           
     347          console.log("GET_CERTIFICATE___"+ certCount + "...certBag Ok"); 
     348
     349          if(certP12bag == null)
     350            {
     351            certP12bag = safeBag.cert;
     352            certpem = "" +  forge.pki.certificateToPem(certP12bag).toString();
     353            certBytesHex = forge.util.bytesToHex(certpem);
     354            }
     355          }
     356        } 
     357      }
     358    }
     359    reader.readAsArrayBuffer(file);
     360  }
     361
     362//funcion que ejecuta el proceso de firma electrónica usando el servicio Murachí
     363function SignFilePDF() {
     364  //cargar el archivo .p12
     365  getCertificate();
     366    var fileInput = document.getElementById("file-sign");
     367    var list = fileInput.files;
     368    var form = $('firmar')[0];
     369    var data = new FormData();
     370    data.append('upload', $("#file-sign")[0].files[0]);
     371    $.ajax({               
     372        url: "https://murachi.cenditel.gob.ve/Murachi/0.1/archivos",
     373        type: "post",
     374        dataType: "json",
     375        data: data,
     376        cache: false,
     377        contentType: false,
     378        processData: false,
     379        xhrFields: {withCredentials: true},
     380        headers: {"Authorization":"Basic YWRtaW46YWRtaW4="},
     381        success: function(response) {
     382            var responseString = JSON.stringify(response);                                     
     383            document.getElementById("seccion1").innerHTML = responseString;
     384           }
     385    )}
    392386
    393387}}}
     
    399393'''Ejemplo:''' {"containerId":"b43ea1f0-2c1a-463e-a0b8-1804e2041f33"}
    400394
    401 '''Sección 2: Preparar firma del archivo'''
     395== Sección 2: Preparar firma del archivo ==
    402396
    403397En esta sección se va a calcular el valor del hash del documento que se envió en la sección 1, en tal sentido antes del cálculo del hash se debe enviar al servidor Murachí toda la información que se agregará al documento tales como el certificado del firmante como información adicional necesaria para la firma electrónica:
     
    413407
    414408{{{
    415 document.getElementById("seccion1").innerHTML = responseString; [[BR]]
    416             var fileId = response.fileId.toString();[[BR]]
    417             alert("antes de leer el certificado");[[BR]]
    418             if(certBytesHex != null) {[[BR]]
    419                 console.log("tengo certificado");[[BR]]
    420                         var cert = certBytesHex;[[BR]]
    421                         console.log("certGet:"+ cert);[[BR]]
    422                         var parameters = JSON.stringify({[[BR]]
    423                                 "fileId":fileId,[[BR]]
    424                                 "certificate":cert,[[BR]]
    425                                 "reason":"Certificado",[[BR]]
    426                                 "location":"CENDITEL",[[BR]]
    427                                 "contact":"582746574336",[[BR]]
    428                                 "signatureVisible":"true"[[BR]]
    429                         });[[BR]]
    430                         console.log("cert...3");[[BR]]
    431                         $.ajax({[[BR]]
    432                             type: 'POST',[[BR]]
    433                             contentType: 'application/json', [[BR]]               
    434                             url:"https://murachi.cenditel.gob.ve/Murachi/0.1/archivos/pdfs",[[BR]]
    435                             dataType: "json",[[BR]]
    436                             data: parameters,[[BR]]
    437                             xhrFields: {withCredentials: true},    [[BR]]   
    438                             headers: {"Authorization":"Basic YWRtaW46YWRtaW4="},[[BR]]
    439                             success: function(data, textStatus, jqXHR) {[[BR]]
    440                                         var responseString = JSON.stringify(data);[[BR]]
    441                                         document.getElementById("seccion2").innerHTML = responseString;[[BR]]
    442                         }[[BR]]
    443     )}[[BR]]
    444 }}}
    445 ----
     409document.getElementById("seccion1").innerHTML = responseString;
     410            var fileId = response.fileId.toString();
     411            alert("antes de leer el certificado");
     412            if(certBytesHex != null) {
     413              console.log("tengo certificado");
     414            var cert = certBytesHex;
     415            console.log("certGet:"+ cert);
     416            var parameters = JSON.stringify({
     417              "fileId":fileId,
     418              "certificate":cert,
     419              "reason":"Certificado",
     420              "location":"CENDITEL",
     421              "contact":"582746574336",
     422              "signatureVisible":"true"
     423            });
     424            console.log("cert...3");
     425            $.ajax({
     426                type: 'POST',
     427                contentType: 'application/json',                
     428                url:"https://murachi.cenditel.gob.ve/Murachi/0.1/archivos/pdfs",
     429                dataType: "json",
     430                data: parameters,
     431                xhrFields: {withCredentials: true},       
     432                headers: {"Authorization":"Basic YWRtaW46YWRtaW4="},
     433                success: function(data, textStatus, jqXHR) {
     434                  var responseString = JSON.stringify(data);
     435                  document.getElementById("seccion2").innerHTML = responseString;
     436                        }
     437    )}
     438}}}
     439
    446440
    447441Si 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.
    448442
     443[[br]]
     444
    449445'''Código completo de la sección 2'''
    450446
    451 
    452 {{{
    453 <!doctype html> [[BR]]
    454 <html>[[BR]]
    455 <head>[[BR]]
    456 <meta charset="utf-8">[[BR]]
    457     <title>Javascript firma p12 Demo</title>[[BR]]
    458     <script type="text/javascript" src="forge.min.js"></script>[[BR]]
    459 </head>[[BR]]
    460 
    461 <script>[[BR]]
    462 
    463 //Funciones de conversión[[BR]]
    464 
    465 function arrayBufferToString( buffer ) [[BR]]
     447{{{
     448<!doctype html>
     449<html>
     450<head>
     451<meta charset="utf-8">
     452    <title>Javascript firma p12 Demo</title>
     453    <script type="text/javascript" src="forge.min.js"></script>
     454</head>
     455
     456<script>
     457
     458//Funciones de conversión
     459
     460function arrayBufferToString( buffer )
    466461{
    467     var binary = '';[[BR]]
    468     var bytes = new Uint8Array( buffer );[[BR]]
    469     var len = bytes.byteLength;[[BR]]
    470     for (var i = 0; i < len; i++) [[BR]]
    471     {[[BR]]
    472         binary += String.fromCharCode( bytes[ i ] );[[BR]]
    473     }[[BR]]
    474     return binary;[[BR]]
    475 }[[BR]]
    476 
    477 //function que obtengo la clave privada y el certificado del archivo .p12[[BR]]
    478 function getCertificate(e)[[BR]]
    479 {[[BR]]
    480     // Get PFX[[BR]]
    481     var fileInput = document.getElementById('pfx');[[BR]]
    482     var file = fileInput.files[0];[[BR]]
    483     // Read it[[BR]]
    484     var reader = new FileReader();[[BR]]
    485     reader.onload = function(e)  {[[BR]]
    486         console.log("*.... cargo el archivo .p12 ....*");[[BR]]
    487         var contents = e.target.result;[[BR]]
    488         pkcs12Der = arrayBufferToString(contents);[[BR]]
    489         pkcs12B64 = forge.util.encode64(pkcs12Der);[[BR]]
    490         var pkcs12Asn1 = forge.asn1.fromDer(pkcs12Der);[[BR]]
    491         var password = $('#pfxp').val();[[BR]]
    492         pkcs12 = forge.pkcs12.pkcs12FromAsn1(pkcs12Asn1, false, password);[[BR]]
    493         // load keys[[BR]]
    494         for(var sci = 0; sci < pkcs12.safeContents.length; ++sci) [[BR]]
    495         {[[BR]]
    496             var safeContents = pkcs12.safeContents[sci];[[BR]]
    497             for(var sbi = 0; sbi < safeContents.safeBags.length; ++sbi) [[BR]]
    498                 {[[BR]]
    499                 var safeBag = safeContents.safeBags[sbi];[[BR]]
    500                 if(safeBag.type === forge.pki.oids.keyBag) [[BR]]
    501                 {[[BR]]
    502                     //Found plain private key[[BR]]
    503                     privateKey = safeBag.key;[[BR]]
    504                 } [[BR]]
    505                 else [[BR]]
    506                 if(safeBag.type === forge.pki.oids.pkcs8ShroudedKeyBag) [[BR]]
    507                 {[[BR]]
    508                     // found encrypted private key[[BR]]
    509                     privateKey = safeBag.key;[[BR]]
    510                 } [[BR]]
    511                 else [[BR]]
    512                     if(safeBag.type === forge.pki.oids.certBag) [[BR]]
    513                     {[[BR]]
    514                         // this bag has a certificate...[[BR]]
    515                         certCount = certCount +1;       [[BR]]                                 
    516                         console.log("GET_CERTIFICATE___"+ certCount + "...certBag Ok");  [[BR]]
    517 
    518                         if(certP12bag == null) [[BR]]
    519                         {[[BR]]
    520                             certP12bag = safeBag.cert;[[BR]]
    521                             certpem = "" +  forge.pki.certificateToPem(certP12bag).toString();[[BR]]
    522                             certBytesHex = forge.util.bytesToHex(certpem);[[BR]]
    523                         }[[BR]]
    524                     }   [[BR]]
    525                 }[[BR]]
    526             }[[BR]]
    527         }[[BR]]
    528         reader.readAsArrayBuffer(file);[[BR]]
    529     }[[BR]]
    530 [[BR]]
     462    var binary = '';
     463    var bytes = new Uint8Array( buffer );
     464    var len = bytes.byteLength;
     465    for (var i = 0; i < len; i++)
     466    {
     467        binary += String.fromCharCode( bytes[ i ] );
     468    }
     469    return binary;
     470}
     471
     472//function que obtengo la clave privada y el certificado del archivo .p12
     473function getCertificate(e)
     474{
     475    // Get PFX
     476    var fileInput = document.getElementById('pfx');
     477    var file = fileInput.files[0];
     478    // Read it
     479    var reader = new FileReader();
     480    reader.onload = function(e)  {
     481  console.log("*.... cargo el archivo .p12 ....*");
     482  var contents = e.target.result;
     483  pkcs12Der = arrayBufferToString(contents);
     484  pkcs12B64 = forge.util.encode64(pkcs12Der);
     485  var pkcs12Asn1 = forge.asn1.fromDer(pkcs12Der);
     486  var password = $('#pfxp').val();
     487  pkcs12 = forge.pkcs12.pkcs12FromAsn1(pkcs12Asn1, false, password);
     488  // load keys
     489  for(var sci = 0; sci < pkcs12.safeContents.length; ++sci)
     490  {
     491      var safeContents = pkcs12.safeContents[sci];
     492      for(var sbi = 0; sbi < safeContents.safeBags.length; ++sbi)
     493    {
     494    var safeBag = safeContents.safeBags[sbi];
     495    if(safeBag.type === forge.pki.oids.keyBag)
     496    {
     497        //Found plain private key
     498              privateKey = safeBag.key;
     499    }
     500    else
     501    if(safeBag.type === forge.pki.oids.pkcs8ShroudedKeyBag)
     502    {
     503            // found encrypted private key
     504        privateKey = safeBag.key;
     505    }
     506    else
     507        if(safeBag.type === forge.pki.oids.certBag)
     508        {
     509      // this bag has a certificate...
     510      certCount = certCount +1;           
     511      console.log("GET_CERTIFICATE___"+ certCount + "...certBag Ok"); 
     512
     513      if(certP12bag == null)
     514      {
     515          certP12bag = safeBag.cert;
     516          certpem = "" +  forge.pki.certificateToPem(certP12bag).toString();
     517          certBytesHex = forge.util.bytesToHex(certpem);
     518      }
     519        }
     520    }
     521      }
     522  }
     523  reader.readAsArrayBuffer(file);
     524    }
     525
    531526//funcion que ejecuta el proceso de firma electrónica usando el servicio Murachí
    532 function SignFilePDF() {[[BR]]
    533     //cargar el archivo .p12[[BR]]
    534     getCertificate();[[BR]]
    535     var fileInput = document.getElementById("file-sign");[[BR]]
    536     var list = fileInput.files;[[BR]]
    537     var form = $('firmar')[0];[[BR]]
    538     var data = new FormData();[[BR]]
    539     data.append('upload', $("#file-sign")[0].files[0]);[[BR]]
    540     $.ajax({              [[BR]]
    541         url: "https://murachi.cenditel.gob.ve/Murachi/0.1/archivos",[[BR]]
    542         type: "post",[[BR]]
    543         dataType: "json",[[BR]]
    544         data: data,[[BR]]
    545         cache: false,[[BR]]
    546         contentType: false,[[BR]]
    547         processData: false,[[BR]]
    548         xhrFields: {withCredentials: true},[[BR]]
    549         headers: {"Authorization":"Basic YWRtaW46YWRtaW4="},[[BR]]
    550         success: function(response) {[[BR]]
    551             var responseString = JSON.stringify(response);      [[BR]]                               
    552             document.getElementById("seccion1").innerHTML = responseString;[[BR]]
    553             var fileId = response.fileId.toString();[[BR]]
    554             alert("antes de leer el certificado");[[BR]]
    555             if(certBytesHex != null) {[[BR]]
    556                 var cert = certBytesHex;[[BR]]
    557                 var parameters = JSON.stringify({[[BR]]
    558                     "fileId":fileId,[[BR]]
    559                     "certificate":cert,[[BR]]
    560                     "reason":"Certificado",[[BR]]
    561                     "location":"CENDITEL",[[BR]]
    562                     "contact":"582746574336",[[BR]]
    563                     "signatureVisible":"true"[[BR]]
    564                 });[[BR]]
    565                
    566                 $.ajax({[[BR]]
    567                     type: 'POST',[[BR]]
    568                     contentType: 'application/json',  [[BR]]             
    569                     url:"https://murachi.cenditel.gob.ve/Murachi/0.1/archivos/pdfs",[[BR]]
    570                     dataType: "json",[[BR]]
    571                     data: parameters,[[BR]]
    572                     xhrFields: {withCredentials: true},   [[BR]]     
    573                     headers: {"Authorization":"Basic YWRtaW46YWRtaW4="},[[BR]]
    574                     success: function(data, textStatus, jqXHR) {[[BR]]
    575                         var responseString = JSON.stringify(data);[[BR]]
    576                         document.getElementById("seccion2").innerHTML = responseString;[[BR]]
    577                     }[[BR]]
    578                 )}[[BR]]
    579            }[[BR]]
    580     )}[[BR]]
     527function SignFilePDF() {
     528    //cargar el archivo .p12
     529    getCertificate();
     530    var fileInput = document.getElementById("file-sign");
     531    var list = fileInput.files;
     532    var form = $('firmar')[0];
     533    var data = new FormData();
     534    data.append('upload', $("#file-sign")[0].files[0]);
     535    $.ajax({             
     536        url: "https://murachi.cenditel.gob.ve/Murachi/0.1/archivos",
     537        type: "post",
     538        dataType: "json",
     539        data: data,
     540        cache: false,
     541        contentType: false,
     542        processData: false,
     543        xhrFields: {withCredentials: true},
     544        headers: {"Authorization":"Basic YWRtaW46YWRtaW4="},
     545        success: function(response) {
     546            var responseString = JSON.stringify(response);                                     
     547            document.getElementById("seccion1").innerHTML = responseString;
     548      var fileId = response.fileId.toString();
     549            alert("antes de leer el certificado");
     550            if(certBytesHex != null) {
     551                var cert = certBytesHex;
     552    var parameters = JSON.stringify({
     553        "fileId":fileId,
     554        "certificate":cert,
     555        "reason":"Certificado",
     556        "location":"CENDITEL",
     557        "contact":"582746574336",
     558        "signatureVisible":"true"
     559    });
     560   
     561    $.ajax({
     562        type: 'POST',
     563        contentType: 'application/json',               
     564        url:"https://murachi.cenditel.gob.ve/Murachi/0.1/archivos/pdfs",
     565        dataType: "json",
     566        data: parameters,
     567        xhrFields: {withCredentials: true},       
     568        headers: {"Authorization":"Basic YWRtaW46YWRtaW4="},
     569        success: function(data, textStatus, jqXHR) {
     570          var responseString = JSON.stringify(data);
     571          document.getElementById("seccion2").innerHTML = responseString;
     572                    }
     573        )}
     574           }
     575    )}
     576
    581577}}}
    582578
     
    584580La respuesta del sistema Murachí es el valor del hash del archivo pdf que se subió al servidor en la sección 1.
    585581
    586 Ejemplo :{"hash":"a3fbfc857e0796b5e5e9fdb8e3183d8e532afe0fe662f3a24eb459f0c22bd472","error":""}[[BR]]
    587 
    588 '''
    589 Sección 3: Completar la firma del archivo'''
     582Ejemplo :{{{ {"hash":"a3fbfc857e0796b5e5e9fdb8e3183d8e532afe0fe662f3a24eb459f0c22bd472","error":""} }}}
     583
     584[[BR]]
     585
     586== Sección 3: Completar la firma del archivo ==
    590587
    591588[[BR]]