source: portal_2019/pruebas_web_crypto_api/testingDigitalSignatureWebCryptography.html @ 9bc9e0d

desarrollo
Last change on this file since 9bc9e0d was 9bc9e0d, checked in by pbuitrago@…>, 5 years ago

pruebas de firma y verificacion en el cliente

  • Property mode set to 100644
File size: 18.2 KB
Line 
1<!DOCTYPE html>
2<html lang="es">
3<head>
4  <meta charset="UTF-8">
5  <title>Firma electrónica con Web Crypto API</title>
6<body>
7
8  <main>
9    <form enctype="multipart/form-data" method="post" id="firmar" name="SignFormat">
10      <h1>Firmar un PDF con un pkcs12 y Murachí REST</h1>
11      <p>Seleccione el archivo que va a firmar electrónicamente</p>
12      <input id="file-sign" class="file" type="file" data-min-file-count="1" name="upload" accept=".pdf" >
13      <input id="inputCertificadoPKCS12" type="file" name="inputinputCertificadoPKCS12" />
14      <button type="button" name="buttonsubmit3" id="buttonsubmit3">Firmar</button>
15    </form>
16    <section id="resultados">
17      <div id="seccion1"></div>
18      <div id="seccion2"></div>
19      <div id="seccion3"></div>
20      <div id="seccion4"></div>
21    </section>
22  </main>
23
24  <!-- Forge 0.7.0 -->
25  <script src="./forge.min.js"></script>
26  <script src="./jquery.min.js"></script>
27  <script>
28
29  // Variables globales
30  var
31      reader = new FileReader(),
32      certificado = "",
33      password = "123456",
34      inputCertificadoPKCS12 = document.querySelector("#inputCertificadoPKCS12"),
35      buttonsubmit3 = document.querySelector("#buttonsubmit3"),
36      decodificado = null,
37      certP12bag = null,
38      certificadoHexadecimal = null,
39      privateKeyRSASSAPKCS1v1_5 = null,
40      privateKeyRSAPSS = null,
41      publicKeyRSAPSS = null,
42      importarLlave = null;
43
44
45
46  /* ----- Funciones ----- */
47    // Función para convertir el certificado de ArrayBuffer a String
48    function convertirArrayBufferAString ( buffer ) {
49      let _certificadoEnString = '';     
50      let _bytes = new Uint8Array( buffer );
51      let _longitudDeCadena = _bytes.byteLength;
52      for (let i = 0; i < _longitudDeCadena; i++) {
53        _certificadoEnString += String.fromCharCode( _bytes[ i ] );
54      }
55      return _certificadoEnString;
56    }
57
58    // Función para convertir el certificado de String a ArrayBuffer
59    function convertirStringArrayBuffer ( data ) {
60      let _arrayBuffer = new ArrayBuffer ( data.length );
61      let writer = new Uint8Array ( _arrayBuffer );
62      for (let i = 0, len = data.length; i < len; i++) {
63        writer[i] = data.charCodeAt ( i );
64      }
65      return _arrayBuffer;
66    }
67
68    // Función para decodificar el .p12 convertido en string
69    function decodificarPKCS12 ( stringBase64 ) {
70      let pkcs12Asn1 = forge.asn1.fromDer( stringBase64 );
71      let pkcs12 = forge.pkcs12.pkcs12FromAsn1( pkcs12Asn1, false, password );
72      return pkcs12;
73    }
74
75     // Función para buscar la llave publica del PKCS#12
76    function buscarLlavePublica ( pkcs12 ) {
77      for ( var sci = 0; sci < pkcs12.safeContents.length; ++sci ) {
78        var safeContents = pkcs12.safeContents[ sci ];
79
80        for ( var sbi = 0; sbi < safeContents.safeBags.length; ++sbi ) {
81          var safeBag = safeContents.safeBags[sbi];
82          if (safeBag.cert != undefined) {
83            console.log("antes de llamar safeBag.cert.publicKey")
84            var publicKey = safeBag.cert.publicKey;
85            console.log("**** publickey ****");
86            console.log(publicKey);
87            console.log("**** publickey ****");
88            var publickeyPem = forge.pki.publicKeyToPem(publicKey);
89            console.log("**** publickeyPem ****");
90            console.log(publickeyPem);
91            console.log("**** publickeyPem ****");
92            var publickeyBytesHex = forge.util.bytesToHex(publickeyPem);
93            console.log("**** publickeyBytesHex ****");
94            console.log(publickeyBytesHex);
95            console.log("**** publickeyBytesHex ****");
96            return publicKey;
97            }
98        }
99      }
100    }
101
102    // Función para buscar la llave privada del PKCS#12
103    function buscarLlavePrivada ( pkcs12 ) {
104      for ( var sci = 0; sci < pkcs12.safeContents.length; ++sci ) {
105        var safeContents = pkcs12.safeContents[ sci ];
106
107        for ( var sbi = 0; sbi < safeContents.safeBags.length; ++sbi ) {
108          var safeBag = safeContents.safeBags[sbi];
109          //if (safeBag.cert != undefined) {
110            //console.log("antes de llamar safeBag.cert.publicKey")
111            //var publicKey = safeBag.cert.publicKey;
112            //console.log("**** publickey ****");
113            //console.log(publicKey);
114            //console.log("**** publickey ****");
115            //}
116
117          if ( safeBag.type === forge.pki.oids.keyBag ) {
118            privateKey = safeBag.key;
119          } else if ( safeBag.type === forge.pki.oids.pkcs8ShroudedKeyBag ) {
120            privateKey = safeBag.key;
121          }
122        }
123      }
124      return privateKey;
125    }
126    //var rsaPublicKey = pki.publicKeyToAsn1(publicKey);
127
128    // Función para convertir la llave publica a PKCS#8
129    function publicKeyToPkcs8 ( publicKeyP12 ) {
130      var rsaPublicKey = forge.pki.publicKeyToAsn1(publicKeyP12);
131      //var publicKeyInfo = forge.pki.wrapRsaPrivateKey(rsaPublicKey);
132      var publicKeyInfoDer = forge.asn1.toDer(rsaPublicKey).getBytes();
133      var publicKeyInfoDerBuff = convertirStringArrayBuffer(publicKeyInfoDer);
134      return publicKeyInfoDerBuff;
135    }
136
137    // Función para convertir la llave privada a PKCS#8
138    function privateKeyToPkcs8 ( privateKeyP12 ) {
139        console.log("function privateKeyToPkcs8 ( privateKeyP12 ) {");
140        console.log(privateKeyP12);
141        console.log("function privateKeyToPkcs8 ( privateKeyP12 ) {");
142      var rsaPrivateKey = forge.pki.privateKeyToAsn1(privateKeyP12);
143      var privateKeyInfo = forge.pki.wrapRsaPrivateKey(rsaPrivateKey);
144      var privateKeyInfoDer = forge.asn1.toDer(privateKeyInfo).getBytes();
145      var privateKeyInfoDerBuff = convertirStringArrayBuffer(privateKeyInfoDer);
146      return privateKeyInfoDerBuff;
147    }
148
149    // Función para convertir un Array Buffer a Hexadecimal
150    function buf2hex ( buffer ) {
151      return Array.prototype.map.call(new Uint8Array(buffer), x => ('00' + x.toString(16)).slice(-2)).join('');
152    }
153
154    // Función para importar la llave privada with RSASSA-PKCS1-v1_5
155    /*
156    function importarLlavePrivada ( llavePrivada ) {
157      var qweasd = crypto.subtle.importKey(
158        "pkcs8", //can be "jwk" (public or private), "spki" (public only), or "pkcs8" (private only)
159        llavePrivada,
160        {   //these are the algorithm options
161          name: "RSASSA-PKCS1-v1_5",
162          hash: { name: "SHA-256" }, //can be "SHA-1", "SHA-256", "SHA-384", or "SHA-512"
163        },
164        false, //whether the key is extractable (i.e. can be used in exportKey)
165        ["sign"] //"verify" for public key import, "sign" for private key imports
166      ).then(function(publicKey){
167        //returns a publicKey (or privateKey if you are importing a private key)
168        console.log(publicKey);
169        privateKeyRSASSAPKCS1v1_5 = publicKey;
170      })
171      .catch(function(err){
172        console.error(err);
173      });
174    }
175
176
177    */
178    // Función para importar la llave privada with RSA-PSS
179    function importarLlavePrivada ( llavePrivada ) {
180        console.log("Clave privada");
181        console.log(llavePrivada);
182        console.log("Clave privada");
183      var qweasd = crypto.subtle.importKey(
184        "pkcs8", //can be "jwk" (public or private), "spki" (public only), or "pkcs8" (private only)
185        llavePrivada,
186        {   //these are the algorithm options
187          name: "RSA-PSS",
188          hash: { name: "SHA-256" }, //can be "SHA-1", "SHA-256", "SHA-384", or "SHA-512"
189        },
190        false, //whether the key is extractable (i.e. can be used in exportKey)
191        ["sign"] //"verify" for public key import, "sign" for private key imports
192      ).then(function(publicKey){
193        //returns a publicKey (or privateKey if you are importing a private key)
194        console.log(publicKey);
195        privateKeyRSAPSS = publicKey;
196      })
197      .catch(function(err){
198        console.error(err);
199      });
200    }
201
202// Función para importar la llave publica with RSA-PSS
203    function importarLlavePublica ( llavePublica ) {
204        console.log("importarLlavePublica llavePublica");
205        console.log(llavePublica);
206        console.log("importarLlavePublica llavePublica");
207      var qweasd = crypto.subtle.importKey(
208        "spki", //can be "jwk" (public or private), "spki" (public only), or "pkcs8" (private only)
209        llavePublica,
210        {   //these are the algorithm options
211          name: "RSA-PSS",
212          hash: { name: "SHA-256" }, //can be "SHA-1", "SHA-256", "SHA-384", or "SHA-512"
213        },
214        false, //whether the key is extractable (i.e. can be used in exportKey)
215        ["verify"] //"verify" for public key import, "sign" for private key imports
216      ).then(function(publicKey){
217        //returns a publicKey (or privateKey if you are importing a private key)}
218        console.log("llavePublica importada");
219        console.log(publicKey);
220        console.log("llavePublica importada");
221        publicKeyRSAPSS = publicKey;
222      })
223      .catch(function(err){
224        console.error(err);
225      });
226    }
227    // Función para convertir el certificado .p12 en hexadecimal
228    function convertirPKCS12aHexadecimal ( pkcs12 ) {
229      for ( var sci = 0; sci < pkcs12.safeContents.length; ++sci ) {
230        var safeContents = pkcs12.safeContents[sci];
231        for(var sbi = 0; sbi < safeContents.safeBags.length; ++sbi) {
232          var safeBag = safeContents.safeBags[sbi];
233          if(safeBag.type === forge.pki.oids.keyBag) {
234            privateKey = safeBag.key;
235          } else if(safeBag.type === forge.pki.oids.pkcs8ShroudedKeyBag) {
236            privateKey = safeBag.key;
237          } else if(safeBag.type === forge.pki.oids.certBag) {
238            if(certP12bag == null) {
239              certP12bag = safeBag.cert;
240              var certpem = forge.pki.certificateToPem(certP12bag);
241              var certBytesHex = forge.util.bytesToHex(certpem);
242            }
243          } 
244        }
245      }
246      return certBytesHex;
247    }
248
249
250    // Función para leer el .p12 luego de cargarlo
251    function leerCertificadoPKCS12 () {
252      let archivoAdjuntado = this.files[0];
253
254      reader.onload = function(e) {
255        var
256          contents = e.target.result,
257          pkcs12Der = convertirArrayBufferAString( contents ),
258          pkcs12B64 = forge.util.encode64( pkcs12Der );
259        decodificado = decodificarPKCS12( pkcs12Der );
260        certificadoHexadecimal = convertirPKCS12aHexadecimal(decodificado);
261        var
262          llavePrivada = buscarLlavePrivada(decodificado),
263          llavePublica = buscarLlavePublica(decodificado),
264          convertirAPKCS8 = privateKeyToPkcs8(llavePrivada),
265          convertirAPuKCS8 = publicKeyToPkcs8(llavePublica);
266
267          importarLlavePrivada(convertirAPKCS8);
268          importarLlavePublica(convertirAPuKCS8);
269      }
270      reader.readAsArrayBuffer(archivoAdjuntado);
271    }
272
273  /* ----- Eventos ----- */
274    // 1. Al adjuntar el archivo .p12 se ejecuta la función que lo lee y se extrae su información
275    inputCertificadoPKCS12.addEventListener('change', leerCertificadoPKCS12, false);
276  /* ----- Eventos ----- */
277
278
279
280   
281function convertStringToArrayBufferView(str)
282{
283    var bytes = new Uint8Array(str.length);
284    for (var iii = 0; iii < str.length; iii++)
285    {
286        bytes[iii] = str.charCodeAt(iii);
287    }
288
289    return bytes;
290} 
291
292var crypto = window.crypto || window.msCrypto;
293
294var promise_key = null;
295
296var private_key_object = null;
297var public_key_object = null;
298
299//var data = "QNimate";
300var data = "7a42eea172776c7a6de6d57aa9958d9654410934f5cfbf483b6135a24543f51c";
301
302var encrypted_hash = null;
303var encrypt_promise = null;
304
305var signature = null;
306
307var decrypt_promise = null;
308
309// Usando el algoritmo  RSA-PSS
310
311if(crypto.subtle)
312{
313    console.log("Antes del alert");
314    alert("Cryptography API Supported");
315
316    promise_key = crypto.subtle.generateKey({name: "RSA-PSS", modulusLength: 2048, publicExponent: new Uint8Array([0x01, 0x00, 0x01]), hash: {name: "SHA-256"}}, false, ["sign", "verify"]);
317
318    promise_key.then(function(key){
319        private_key_object = key.privateKey;
320        console.log("******// public_key_object //******");
321        console.log(public_key_object);
322        console.log("******// public_key_object //******");
323        public_key_object = key.publicKey;
324        console.log("****.. antes del encrypt_data()..****");
325        encrypt_data();
326    });
327
328    promise_key.catch = function(e){
329
330        console.log(e.message);
331    }
332   
333   
334}
335else
336{
337    alert("Cryptography API not Supported");
338}
339
340function encrypt_data()
341{
342    console.log("function encrypt_data()");
343    console.log("*** inicio private_key_object ***");
344    console.log(private_key_object);
345    console.log("*** fin private_key_object ***");
346    console.log("*** inicio privatekey ***");
347    console.log(privateKeyRSAPSS);
348    console.log("*** fin privatekey ***");
349
350    if(privateKeyRSAPSS==null) {
351        encrypt_promise = crypto.subtle.sign({name: "RSA-PSS", saltLength: 128, }, private_key_object, convertStringToArrayBufferView(data));
352
353        encrypt_promise.then(
354            function(result_signature){
355                signature = result_signature; //signature generated
356                console.log("**************************************");
357                console.log(signature);
358                console.log("**************************************");
359                console.log("****.. antes del decrypt_data()..****");
360                decrypt_data();
361            },
362            function(e){
363                console.log(e);
364            }
365        );
366    }
367    else {
368
369        encrypt_promise = crypto.subtle.sign({name: "RSA-PSS", saltLength: 128, }, privateKeyRSAPSS, convertStringToArrayBufferView(data));
370
371        encrypt_promise.then(
372            function(result_signature){
373                signature = result_signature; //signature generated
374                console.log("**************************************");
375                console.log(signature);
376                console.log("**************************************");
377                console.log("****.. antes del decrypt_data()..****");
378                decrypt_data();
379            },
380            function(e){
381                console.log(e);
382            }
383        );
384    }
385}
386
387function decrypt_data()
388{
389    if(publicKeyRSAPSS == null) {
390        console.log("function decrypt_data()");
391        console.log("******// public_key_object decrypt_data() //******");
392        console.log(public_key_object);
393        console.log("******// public_key_object decrypt_data() //******");
394        decrypt_promise = crypto.subtle.verify({name: "RSA-PSS", saltLength: 128, }, public_key_object, signature, convertStringToArrayBufferView(data));
395
396            decrypt_promise.then(
397                function(result){
398                    console.log(result);//true or false
399                },
400            function(e){
401                console.log(e.message);
402            }
403        );
404    }
405    else {
406        console.log("function decrypt_data()");
407        console.log("******// publicKeyRSAPSS decrypt_data() //******");
408        console.log(publicKeyRSAPSS);
409        console.log("******// publicKeyRSAPSS decrypt_data() //******");
410        decrypt_promise = crypto.subtle.verify({name: "RSA-PSS", saltLength: 128, }, publicKeyRSAPSS, signature, convertStringToArrayBufferView(data));
411        decrypt_promise.then(
412            function(result){
413                console.log(result);//true or false
414            },
415            function(e){
416                console.log(e.message);
417            }
418        );
419
420    }
421
422}
423/*
424// Usando el algoritmo  RSASSA-PKCS1-v1_5
425if(crypto.subtle)
426{
427    console.log("Antes del alert");
428    alert("Cryptography API Supported");
429
430    promise_key = crypto.subtle.generateKey({name: "RSASSA-PKCS1-v1_5", modulusLength: 2048, publicExponent: new Uint8Array([1, 0, 1]), hash: {name: "SHA-256"}}, false, ["sign", "verify"]);
431
432    promise_key.then(function(key){
433        private_key_object = key.privateKey;
434        public_key_object = key.publicKey;
435        console.log("****.. antes del encrypt_data()..****");
436        encrypt_data();
437    });
438
439    promise_key.catch = function(e){
440
441        console.log(e.message);
442    }
443}
444else
445{
446    alert("Cryptography API not Supported");
447}
448
449function encrypt_data()
450{
451    console.log("function encrypt_data()");
452    //encrypt_promise = crypto.subtle.sign({name: "RSASSA-PKCS1-v1_5"}, private_key_object, convertStringToArrayBufferView(data));
453    console.log("*** inicio private_key_object ***");
454    console.log(private_key_object);
455    console.log("*** fin private_key_object ***");
456    console.log("*** inicio privatekey ***");
457    console.log(privateKeyRSASSAPKCS1v1_5);
458    console.log("*** fin privatekey ***");
459
460    if(privateKeyRSASSAPKCS1v1_5 == null) {
461        encrypt_promise = crypto.subtle.sign({name: "RSASSA-PKCS1-v1_5"}, private_key_object, convertStringToArrayBufferView(data));
462
463        encrypt_promise.then(
464            function(result_signature){
465                signature = result_signature; //signature generated
466                console.log("**************************************");
467                console.log(signature);
468                console.log("**************************************");
469                console.log("****.. antes del decrypt_data()..****");
470                decrypt_data();
471            },
472            function(e){
473                console.log(e);
474            }
475        );
476    } else {
477         console.log("privateKey != Null");
478         encrypt_promise = crypto.subtle.sign({name: "RSASSA-PKCS1-v1_5"}, privateKeyRSASSAPKCS1v1_5, convertStringToArrayBufferView(data));
479
480        encrypt_promise.then(
481            function(result_signature){
482                signature = result_signature; //signature generated
483                console.log("**************************************");
484                console.log(signature);
485                console.log("**************************************");
486                console.log("****.. antes del decrypt_data()..****");
487                decrypt_data();
488            },
489            function(e){
490                console.log(e);
491            }
492        );
493    }
494}
495
496function decrypt_data()
497{
498    console.log("function decrypt_data()");
499    decrypt_promise = crypto.subtle.verify({name: "RSASSA-PKCS1-v1_5"}, public_key_object, signature, convertStringToArrayBufferView(data));
500
501    decrypt_promise.then(
502        function(result){
503            console.log(result);//true or false
504        },
505        function(e){
506            console.log(e.message);
507        }
508    );
509}
510*/
511
512  buttonsubmit3.addEventListener('click', function() {
513      encrypt_data();
514    }, true);
515
516</script>
517</body>
518</html>
Note: See TracBrowser for help on using the repository browser.