source: aportesmurachi/tahel/Murachi-pre/sign2.html

Last change on this file was 12e6ddf, checked in by Antonio Araujo <aaraujo@…>, 7 years ago

Agregados los directorio de aportes de Tahel al control de versiones.

  • Property mode set to 100644
File size: 8.2 KB
Line 
1<!doctype html>
2<html>
3<head>
4<meta charset="utf-8">
5    <title>Javascript Signing Demo</title>
6
7        <script src='https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js'></script>
8        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
9        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap-theme.min.css">
10        <style type="text/css">
11        body,td,th {
12        font-family: Calibri;
13        color: #000;
14}
15a:link {
16        color: #0000FF;
17        font-weight: bold;
18        text-decoration: none;
19}
20a:visited {
21        text-decoration: none;
22        color: #00F;
23}
24a:hover {
25        text-decoration: none;
26        color: #0000FF;
27}
28a:active {
29        text-decoration: none;
30        color: #00F;
31}
32    body {
33        margin-left: 30px;
34        margin-top: 30px;
35        margin-right: 30px;
36        margin-bottom: 30px;
37}
38    </style>
39        <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
40    <script src="forge.min.js"></script>
41</head>
42<body>
43
44<script>
45
46
47// Conversion functions
48function stringToArrayBuffer(data)
49        {
50        var arrBuff = new ArrayBuffer(data.length);
51        var writer = new Uint8Array(arrBuff);
52        for (var i = 0, len = data.length; i < len; i++) 
53                {
54                writer[i] = data.charCodeAt(i);
55                }
56        return arrBuff;
57        }
58function arrayBufferToString( buffer ) 
59        {
60        var binary = '';
61        var bytes = new Uint8Array( buffer );
62        var len = bytes.byteLength;
63        for (var i = 0; i < len; i++) 
64                {
65                binary += String.fromCharCode( bytes[ i ] );
66                }
67        return binary;
68        }
69
70// From Private Key to a PKCS#8
71function privateKeyToPkcs8(privateKey) 
72        {
73        var rsaPrivateKey = forge.pki.privateKeyToAsn1(privateKey);
74        var privateKeyInfo = forge.pki.wrapRsaPrivateKey(rsaPrivateKey);
75        var privateKeyInfoDer = forge.asn1.toDer(privateKeyInfo).getBytes();
76        var privateKeyInfoDerBuff = stringToArrayBuffer(privateKeyInfoDer);
77        return privateKeyInfoDerBuff;
78        }
79
80// From Public Key to a PKCS#8
81function publicKeyToPkcs8(pk) 
82        {
83        var subjectPublicKeyInfo = forge.pki.publicKeyToAsn1(pk);
84        var der = forge.asn1.toDer(subjectPublicKeyInfo).getBytes();
85        return stringToArrayBuffer(der);
86        }
87
88function CreateDownload(text)
89{
90        var textFile = null;
91    var data = new Blob([text], {type: 'application/x-x509-user-cert'});
92    textFile = window.URL.createObjectURL(data);
93    return textFile;
94}
95
96function CertInfo(cert)
97        {
98        // Convert to ASN
99        var asn1Cert = forge.pki.certificateToAsn1(cert);
100
101    // Convert to DER format
102    var p12Der = forge.asn1.toDer(asn1Cert).getBytes();
103
104    // Encode with Base64
105    var p12b64  = forge.util.encode64(p12Der);
106
107        var j = '<a href="data:application/x-x509-ca-cert;base64,' + p12b64 + '" download="cert.der">Certificate Information</a><br>';
108        try { j += "NAME: " + cert.subject.getField('CN').value + "<br>" } catch (err) {};
109        try { j += "MAIL: " + cert.subject.getField('E').value + "<br>" } catch(err) {};
110        try { j += "ISSUER: " + cert.issuer.getField('CN').value + "<br>" } catch(err) {};
111        return j;
112        }
113       
114
115// Create a CryptoKey from  from a PKCS#12 Private Key
116function importCryptoKeyPkcs8(privateKey,extractable) 
117        {
118        var privateKeyInfoDerBuff = privateKeyToPkcs8(privateKey);
119
120        //Importa la clave en la webcrypto
121        return crypto.subtle.importKey(
122                'pkcs8',
123                privateKeyInfoDerBuff,
124                { name: "RSASSA-PKCS1-v1_5", hash:{name:"SHA-256"}},
125                extractable,
126                ["sign"]);
127        }
128
129function Verify()
130        {
131    var pem = forge.util.decode64($('#pfxc').val());
132    var signature64 = $('#pfxs').val();
133    var signature = forge.util.decode64(signature64);
134    var data = $('#pfxd').val();
135    var cert = forge.pki.certificateFromPem(pem);
136
137    window.crypto.subtle.importKey("spki",publicKeyToPkcs8(cert.publicKey),
138        {   
139        name: "RSASSA-PKCS1-v1_5",
140        hash: {name: "SHA-256"}, 
141            },
142        false,
143            ["verify"]
144        ).then(function(k)
145                {
146                        window.crypto.subtle.verify(
147                                {
148                                name: "RSASSA-PKCS1-v1_5",
149                                },
150                                k, //from generateKey or importKey above
151                                stringToArrayBuffer(signature), //ArrayBuffer of the signature
152                            stringToArrayBuffer(data) //ArrayBuffer of the data
153                                ).then(function(isvalid)
154                                {
155                                //returns a boolean on whether the signature is true or not
156                                if (!isvalid)
157                                        {
158                                        var msg = 'Invalid digital Signature!<br>';
159                                        msg += 'Signed Document: ';
160                                        msg +=  forge.util.decode64($('#pfxd').val());
161       
162                                        msg += '<br>';
163                                        msg += CertInfo(cert);
164                       
165                       
166                                        $('#dr').html(msg);
167                                        }
168                            else
169                                        {
170                                        var msg = 'Valid Digital Signature!<br>';
171                                        msg += 'Signed Document: ';
172                                        msg +=  forge.util.decode64($('#pfxd').val());
173       
174                                        msg += '<br>';
175                                        msg += CertInfo(cert);
176                       
177                       
178                                        $('#dr').html(msg);
179                                        }
180                                }).catch(function(err)
181                                        {
182                                        $('#dr').html('Invalid Digital Signature!');
183                                        });
184                                }
185                               
186                        );
187        }
188
189function Sign2()
190        {
191        // Get PFX
192        var fileInput = document.getElementById('pfx');
193        var file = fileInput.files[0];
194
195        // Read it
196        var reader = new FileReader();
197        reader.onload = function(e) 
198                {
199                var contents = e.target.result;
200                var pkcs12Der = arrayBufferToString(contents)
201                var pkcs12B64 = forge.util.encode64(pkcs12Der);
202                var privateKey;
203                var pkcs12Asn1 = forge.asn1.fromDer(pkcs12Der);
204                var password = $('#pfxp').val();
205               
206                var pkcs12 = forge.pkcs12.pkcs12FromAsn1(pkcs12Asn1, false, password);
207                // load keys
208                for(var sci = 0; sci < pkcs12.safeContents.length; ++sci) 
209                        {
210                        var safeContents = pkcs12.safeContents[sci];
211                        for(var sbi = 0; sbi < safeContents.safeBags.length; ++sbi) 
212                                {
213                                var safeBag = safeContents.safeBags[sbi];
214                                if(safeBag.type === forge.pki.oids.keyBag) 
215                                        {
216                                        //Found plain private key
217                                        privateKey = safeBag.key;
218                                        } 
219                                else 
220                                if(safeBag.type === forge.pki.oids.pkcs8ShroudedKeyBag) 
221                                        {
222                                        // found encrypted private key
223                                        privateKey = safeBag.key;
224                                        } 
225                                else 
226                                if(safeBag.type === forge.pki.oids.certBag) 
227                                        {
228                                        // this bag has a certificate...
229                                        cert = safeBag.cert;
230                                        }       
231                                }
232                        }
233
234                importCryptoKeyPkcs8(privateKey,true).then(function(cryptoKey) 
235                        {
236                        // Signed!
237                       
238                        // Empty stuff
239                        var ser = forge.util.encode64($('#form1').serialize());
240                        var digestToSignBuf = stringToArrayBuffer(ser);
241                        $('#pfxd').val(ser);
242                        var pem = forge.pki.certificateToPem(cert);
243                        $('#pfxc').val(forge.util.encode64(pem));
244
245                        crypto.subtle.sign(
246                                {name: "RSASSA-PKCS1-v1_5"},
247                                cryptoKey,
248                                digestToSignBuf)
249                                .then(function(signature){
250                                        sign = arrayBufferToString(signature);
251                                        signatureB64 = forge.util.encode64(sign);
252                                        $('#pfxs').val(signatureB64);
253                                       
254                                       
255                                       
256                        });
257               
258                });
259
260        }
261
262        reader.readAsArrayBuffer(file);
263        }
264
265function Sign1()
266        {
267        // Check validity
268        var myForm = document.getElementById('form1');
269        if (myForm.checkValidity()) 
270                {
271            Sign2();
272        }
273        }
274
275</script>
276
277<strong>Form to fill</strong>
278<hr>
279<form name="form1" id="form1" method="post" action="">
280  <label for="firstname">First name:</label>
281  <input type="text" class="form-control" name="firstname" id="firstname" required><br>
282  <label for="lastname">Last name:</label>
283  <input type="text" class="form-control" name="lastname" id="lastname" required><br>
284</form>
285 
286 <label for="pfx">Select PFX/P12 file:</label><br>
287 <input name="pfx" class="form-control" type="file" id="pfx" accept=".pfx,.p12" required /><br>
288  <label for="pfxp">Enter Private Key password:</label><br>
289 <input name="pfxp" class="form-control" type="password" id="pfxp" /><br>
290
291<button type="button" name="buttonsubmit2" id="buttonsubmit2" onclick="Sign1();" class="btn btn-primary btn-lg">SIGN DOCUMENT</button>
292
293<p>&nbsp;</p><br><br>
294<p><strong>Output</strong></p>
295<hr>
296<p>
297  <label for="pfxs">Signature:</label><textarea name="pfxs" id="pfxs" class="form-control" ></textarea><br>
298  <label for="pfxd">Data signed:</label><textarea name="pfxd" id="pfxd"  class="form-control" ></textarea><br>
299  <label for="pfxc">Certificate:</label><textarea name="pfxc" id="pfxc"  class="form-control"  ></textarea><br>
300  <button type="button" name="buttonsubmit3" id="buttonsubmit3" onclick="Verify();" class="btn btn-primary btn-lg">VERIFY SIGNATURE</button>
301</p>
302
303<div id="dr"></div>
304
305</body>
306</html>
Note: See TracBrowser for help on using the repository browser.