-
-
Save sergio/73c75ed46bc035a43b55ff1d941e4d29 to your computer and use it in GitHub Desktop.
Revisions
-
Andrei revised this gist
Apr 13, 2016 . 1 changed file with 18 additions and 18 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -229,25 +229,25 @@ }) // Test encryption generateKey(encryptAlgorithm, scopeEncrypt).then(function(keys) { var title = document.createElement('h2') title.innerHTML = 'Encryption' document.querySelector('body').appendChild(title) encryptData(vector, keys.publicKey, _data).then(function(encryptedData) { var sigT = document.createElement('h2') sigT.innerHTML = 'Encrypted text:' document.querySelector('body').appendChild(sigT) var divSig = document.createElement('div') divSig.innerHTML = arrayBufferToBase64(encryptedData) document.querySelector('body').appendChild(divSig) decryptData(vector, keys.privateKey, encryptedData).then(function(result) { var verT = document.createElement('h2') verT.innerHTML = 'Encryption outcome:' document.querySelector('body').appendChild(verT) var divOut = document.createElement('div') divOut.innerHTML = (arrayBufferToText(result) === _data)?'Success':'Failed'; document.querySelector('body').appendChild(divOut) }) }) }) } </script> -
Andrei revised this gist
Apr 13, 2016 . 1 changed file with 100 additions and 30 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,15 +1,15 @@ <html> <head> <script> function generateKey(alg, scope) { return new Promise(function(resolve) { var genkey = crypto.subtle.generateKey(alg, true, scope) genkey.then(function (pair) { resolve(pair) }) }) } function arrayBufferToBase64String(arrayBuffer) { var byteArray = new Uint8Array(arrayBuffer) var byteString = '' @@ -18,7 +18,7 @@ } return btoa(byteString) } function base64StringToArrayBuffer(b64str) { var byteStr = atob(b64str) var bytes = new Uint8Array(byteStr.length) @@ -27,7 +27,7 @@ } return bytes.buffer } function textToArrayBuffer(str) { var buf = unescape(encodeURIComponent(str)) // 2 bytes for each char var bufView = new Uint8Array(buf.length) @@ -36,11 +36,21 @@ } return bufView } function arrayBufferToText(arrayBuffer) { var byteArray = new Uint8Array(arrayBuffer) var str = '' for (var i=0; i<byteArray.byteLength; i++) { str += String.fromCharCode(byteArray[i]) } return str } function arrayBufferToBase64(arr) { return btoa(String.fromCharCode.apply(null, new Uint8Array(arr))) } function convertBinaryToPem(binaryData, label) { var base64Cert = arrayBufferToBase64String(binaryData) var pemCert = "-----BEGIN " + label + "-----\r\n" @@ -57,7 +67,7 @@ pemCert += "-----END " + label + "-----\r\n" return pemCert } function convertPemToBinary(pem) { var lines = pem.split('\n') var encoded = '' @@ -72,7 +82,7 @@ } return base64StringToArrayBuffer(encoded) } function importPublicKey(pemKey) { return new Promise(function(resolve) { var importer = crypto.subtle.importKey("spki", convertPemToBinary(pemKey), signAlgorithm, true, ["verify"]) @@ -81,7 +91,7 @@ }) }) } function importPrivateKey(pemKey) { return new Promise(function(resolve) { var importer = crypto.subtle.importKey("pkcs8", convertPemToBinary(pemKey), signAlgorithm, true, ["sign"]) @@ -90,7 +100,7 @@ }) }) } function exportPublicKey(keys) { return new Promise(function(resolve) { window.crypto.subtle.exportKey('spki', keys.publicKey). @@ -99,7 +109,7 @@ }) }) } function exportPrivateKey(keys) { return new Promise(function(resolve) { var expK = window.crypto.subtle.exportKey('pkcs8', keys.privateKey) @@ -108,7 +118,7 @@ }) }) } function exportPemKeys(keys) { return new Promise(function(resolve) { exportPublicKey(keys).then(function(pubKey) { @@ -118,16 +128,37 @@ }) }) } function signData(key, data) { return window.crypto.subtle.sign(signAlgorithm, key, textToArrayBuffer(data)) } function testVerifySig(pub, sig, data) { return crypto.subtle.verify(signAlgorithm, pub, sig, data) } function encryptData(vector, key, data) { return crypto.subtle.encrypt( { name: "RSA-OAEP", iv: vector }, key, textToArrayBuffer(data) ) } function decryptData(vector, key, data) { return crypto.subtle.decrypt( { name: "RSA-OAEP", iv: vector }, key, data ) } // Test everything var signAlgorithm = { name: "RSASSA-PKCS1-v1_5", @@ -138,47 +169,86 @@ extractable: false, publicExponent: new Uint8Array([1, 0, 1]) } var encryptAlgorithm = { name: "RSA-OAEP", modulusLength: 2048, publicExponent: new Uint8Array([1, 0, 1]), extractable: false, hash: { name: "SHA-256" } } var crypto = window.crypto || window.msCrypto if (crypto.subtle) { var _signedData var _data = "test" var scopeSign = ["sign", "verify"] var scopeEncrypt = ["encrypt", "decrypt"] var vector = crypto.getRandomValues(new Uint8Array(16)) // Test signature generateKey(signAlgorithm, scopeSign).then(function(pair) { exportPemKeys(pair).then(function(keys) { var title = document.createElement('h2') title.innerHTML = 'Signature' document.querySelector('body').appendChild(title) var divS = document.createElement('div') var divP = document.createElement('div') divS.innerHTML = JSON.stringify(keys.privateKey) divP.innerHTML = JSON.stringify(keys.publicKey) document.querySelector('body').appendChild(divS) document.querySelector('body').appendChild(document.createElement('br')) document.querySelector('body').appendChild(divP) signData(pair.privateKey, _data).then(function(signedData) { var sigT = document.createElement('h2') sigT.innerHTML = 'Signature:' document.querySelector('body').appendChild(sigT) var divSig = document.createElement('div') divSig.innerHTML = arrayBufferToBase64(signedData) document.querySelector('body').appendChild(divSig) _signedData = signedData testVerifySig(pair.publicKey, signedData, textToArrayBuffer(_data)).then(function(result) { var verT = document.createElement('h2') verT.innerHTML = 'Signature outcome:' document.querySelector('body').appendChild(verT) var divOut = document.createElement('div') divOut.innerHTML = (result)?'Success':'Failed'; document.querySelector('body').appendChild(divOut) }) }) // load keys and re-check signature importPublicKey(keys.publicKey).then(function(key) { testVerifySig(key, _signedData, textToArrayBuffer(_data)).then(function(result) { console.log("Signature verified after importing PEM public key:", result) }) }) // should output `Signature verified: true` twice in the console }) }) // Test encryption generateKey(encryptAlgorithm, scopeEncrypt).then(function(keys) { var title = document.createElement('h2') title.innerHTML = 'Encryption' document.querySelector('body').appendChild(title) encryptData(vector, keys.publicKey, _data).then(function(encryptedData) { var sigT = document.createElement('h2') sigT.innerHTML = 'Encrypted text:' document.querySelector('body').appendChild(sigT) var divSig = document.createElement('div') divSig.innerHTML = arrayBufferToBase64(encryptedData) document.querySelector('body').appendChild(divSig) decryptData(vector, keys.privateKey, encryptedData).then(function(result) { var verT = document.createElement('h2') verT.innerHTML = 'Encryption outcome:' document.querySelector('body').appendChild(verT) var divOut = document.createElement('div') divOut.innerHTML = (arrayBufferToText(result) === _data)?'Success':'Failed'; document.querySelector('body').appendChild(divOut) }) }) }) } </script> </head> -
Andrei revised this gist
Apr 13, 2016 . 2 changed files with 186 additions and 180 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,186 @@ <html> <head> <script> function generateSigKey(alg) { return new Promise(function(resolve) { var genkey = crypto.subtle.generateKey(alg, true, ["sign", "verify"]) genkey.then(function (pair) { resolve(pair) }) }) } function arrayBufferToBase64String(arrayBuffer) { var byteArray = new Uint8Array(arrayBuffer) var byteString = '' for (var i=0; i<byteArray.byteLength; i++) { byteString += String.fromCharCode(byteArray[i]) } return btoa(byteString) } function base64StringToArrayBuffer(b64str) { var byteStr = atob(b64str) var bytes = new Uint8Array(byteStr.length) for (var i = 0; i < byteStr.length; i++) { bytes[i] = byteStr.charCodeAt(i) } return bytes.buffer } function textToArrayBuffer(str) { var buf = unescape(encodeURIComponent(str)) // 2 bytes for each char var bufView = new Uint8Array(buf.length) for (var i=0; i < buf.length; i++) { bufView[i] = buf.charCodeAt(i) } return bufView } function arraySignatureToBase64(arr) { return btoa(String.fromCharCode.apply(null, new Uint8Array(arr))) } function convertBinaryToPem(binaryData, label) { var base64Cert = arrayBufferToBase64String(binaryData) var pemCert = "-----BEGIN " + label + "-----\r\n" var nextIndex = 0 var lineLength while (nextIndex < base64Cert.length) { if (nextIndex + 64 <= base64Cert.length) { pemCert += base64Cert.substr(nextIndex, 64) + "\r\n" } else { pemCert += base64Cert.substr(nextIndex) + "\r\n" } nextIndex += 64 } pemCert += "-----END " + label + "-----\r\n" return pemCert } function convertPemToBinary(pem) { var lines = pem.split('\n') var encoded = '' for(var i = 0;i < lines.length;i++){ if (lines[i].trim().length > 0 && lines[i].indexOf('-BEGIN RSA PRIVATE KEY-') < 0 && lines[i].indexOf('-BEGIN RSA PUBLIC KEY-') < 0 && lines[i].indexOf('-END RSA PRIVATE KEY-') < 0 && lines[i].indexOf('-END RSA PUBLIC KEY-') < 0) { encoded += lines[i].trim() } } return base64StringToArrayBuffer(encoded) } function importPublicKey(pemKey) { return new Promise(function(resolve) { var importer = crypto.subtle.importKey("spki", convertPemToBinary(pemKey), signAlgorithm, true, ["verify"]) importer.then(function(key) { resolve(key) }) }) } function importPrivateKey(pemKey) { return new Promise(function(resolve) { var importer = crypto.subtle.importKey("pkcs8", convertPemToBinary(pemKey), signAlgorithm, true, ["sign"]) importer.then(function(key) { resolve(key) }) }) } function exportPublicKey(keys) { return new Promise(function(resolve) { window.crypto.subtle.exportKey('spki', keys.publicKey). then(function(spki) { resolve(convertBinaryToPem(spki, "RSA PUBLIC KEY")) }) }) } function exportPrivateKey(keys) { return new Promise(function(resolve) { var expK = window.crypto.subtle.exportKey('pkcs8', keys.privateKey) expK.then(function(pkcs8) { resolve(convertBinaryToPem(pkcs8, "RSA PRIVATE KEY")) }) }) } function exportPemKeys(keys) { return new Promise(function(resolve) { exportPublicKey(keys).then(function(pubKey) { exportPrivateKey(keys).then(function(privKey) { resolve({publicKey: pubKey, privateKey: privKey}) }) }) }) } function signData(key, data) { var buffer = textToArrayBuffer(data) return window.crypto.subtle.sign(signAlgorithm, key, buffer) } function testVerifySig(pub, sig, data) { return crypto.subtle.verify(signAlgorithm, pub, sig, data) } // Test everything var signAlgorithm = { name: "RSASSA-PKCS1-v1_5", hash: { name: "SHA-256" }, modulusLength: 2048, extractable: false, publicExponent: new Uint8Array([1, 0, 1]) } var crypto = window.crypto || window.msCrypto if (crypto.subtle) { var _signedData var _toSign = "test" generateSigKey(signAlgorithm).then(function(pair) { exportPemKeys(pair).then(function(keys) { var divS = document.createElement('div') var divP = document.createElement('div') divS.innerHTML = JSON.stringify(keys.privateKey) divP.innerHTML = JSON.stringify(keys.publicKey) document.querySelector('body').appendChild(divS) document.querySelector('body').appendChild(document.createElement('br')) document.querySelector('body').appendChild(divP) signData(pair.privateKey, _toSign).then(function(signedData) { var sigT = document.createElement('h2') sigT.innerHTML = 'Signature:' document.querySelector('body').appendChild(sigT) var divSig = document.createElement('div') divSig.innerHTML = arraySignatureToBase64(signedData) document.querySelector('body').appendChild(divSig) _signedData = signedData testVerifySig(pair.publicKey, signedData, textToArrayBuffer(_toSign)).then(function(match) { var verT = document.createElement('h2') verT.innerHTML = 'Outcome:' document.querySelector('body').appendChild(verT) var divOut = document.createElement('div') divOut.innerHTML = (match)?'Success':'Failed'; document.querySelector('body').appendChild(divOut) }) }) // load keys and re-check signature importPublicKey(keys.publicKey).then(function(key) { testVerifySig(key, _signedData, textToArrayBuffer(_toSign)).then(function(match) { console.log("Signature verified after importing PEM public key:", match) }) }) // should output `Signature verified: true` twice in the console }) }) } </script> </head> <body></body> </html> This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,180 +0,0 @@ -
Andrei revised this gist
Apr 13, 2016 . 1 changed file with 100 additions and 87 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,167 +1,180 @@ function generateSigKey(alg) { return new Promise(function(resolve) { var genkey = crypto.subtle.generateKey(alg, true, ["sign", "verify"]) genkey.then(function (pair) { resolve(pair) }) }) } function arrayBufferToBase64String(arrayBuffer) { var byteArray = new Uint8Array(arrayBuffer) var byteString = '' for (var i=0; i<byteArray.byteLength; i++) { byteString += String.fromCharCode(byteArray[i]) } return btoa(byteString) } function base64StringToArrayBuffer(b64str) { var byteStr = atob(b64str) var bytes = new Uint8Array(byteStr.length) for (var i = 0; i < byteStr.length; i++) { bytes[i] = byteStr.charCodeAt(i) } return bytes.buffer } function textToArrayBuffer(str) { var buf = unescape(encodeURIComponent(str)) // 2 bytes for each char var bufView = new Uint8Array(buf.length) for (var i=0; i < buf.length; i++) { bufView[i] = buf.charCodeAt(i) } return bufView } function arraySignatureToBase64(arr) { return btoa(String.fromCharCode.apply(null, new Uint8Array(arr))) } function convertBinaryToPem(binaryData, label) { var base64Cert = arrayBufferToBase64String(binaryData) var pemCert = "-----BEGIN " + label + "-----\r\n" var nextIndex = 0 var lineLength while (nextIndex < base64Cert.length) { if (nextIndex + 64 <= base64Cert.length) { pemCert += base64Cert.substr(nextIndex, 64) + "\r\n" } else { pemCert += base64Cert.substr(nextIndex) + "\r\n" } nextIndex += 64 } pemCert += "-----END " + label + "-----\r\n" return pemCert } function convertPemToBinary(pem) { var lines = pem.split('\n') var encoded = '' for(var i = 0;i < lines.length;i++){ if (lines[i].trim().length > 0 && lines[i].indexOf('-BEGIN RSA PRIVATE KEY-') < 0 && lines[i].indexOf('-BEGIN RSA PUBLIC KEY-') < 0 && lines[i].indexOf('-END RSA PRIVATE KEY-') < 0 && lines[i].indexOf('-END RSA PUBLIC KEY-') < 0) { encoded += lines[i].trim() } } return base64StringToArrayBuffer(encoded) } function importPublicKey(pemKey) { return new Promise(function(resolve) { var importer = crypto.subtle.importKey("spki", convertPemToBinary(pemKey), signAlgorithm, true, ["verify"]) importer.then(function(key) { resolve(key) }) }) } function importPrivateKey(pemKey) { return new Promise(function(resolve) { var importer = crypto.subtle.importKey("pkcs8", convertPemToBinary(pemKey), signAlgorithm, true, ["sign"]) importer.then(function(key) { resolve(key) }) }) } function exportPublicKey(keys) { return new Promise(function(resolve) { window.crypto.subtle.exportKey('spki', keys.publicKey). then(function(spki) { resolve(convertBinaryToPem(spki, "RSA PUBLIC KEY")) }) }) } function exportPrivateKey(keys) { return new Promise(function(resolve) { var expK = window.crypto.subtle.exportKey('pkcs8', keys.privateKey) expK.then(function(pkcs8) { resolve(convertBinaryToPem(pkcs8, "RSA PRIVATE KEY")) }) }) } function exportPemKeys(keys) { return new Promise(function(resolve) { exportPublicKey(keys).then(function(pubKey) { exportPrivateKey(keys).then(function(privKey) { resolve({publicKey: pubKey, privateKey: privKey}) }) }) }) } function signData(key, data) { var buffer = textToArrayBuffer(data) return window.crypto.subtle.sign(signAlgorithm, key, buffer) } function testVerifySig(pub, sig, data) { return crypto.subtle.verify(signAlgorithm, pub, sig, data) } // Test everything var signAlgorithm = { name: "RSASSA-PKCS1-v1_5", hash: { name: "SHA-256" }, modulusLength: 2048, extractable: false, publicExponent: new Uint8Array([1, 0, 1]) } var crypto = window.crypto || window.msCrypto if (crypto.subtle) { var _signedData var _toSign = "test" generateSigKey(signAlgorithm).then(function(pair) { exportPemKeys(pair).then(function(keys) { var divS = document.createElement('div') var divP = document.createElement('div') divS.innerHTML = JSON.stringify(keys.privateKey) divP.innerHTML = JSON.stringify(keys.publicKey) document.querySelector('body').appendChild(divS) document.querySelector('body').appendChild(document.createElement('br')) document.querySelector('body').appendChild(divP) signData(pair.privateKey, _toSign).then(function(signedData) { var sigT = document.createElement('h2') sigT.innerHTML = 'Signature:' document.querySelector('body').appendChild(sigT) var divSig = document.createElement('div') divSig.innerHTML = arraySignatureToBase64(signedData) document.querySelector('body').appendChild(divSig) _signedData = signedData testVerifySig(pair.publicKey, signedData, textToArrayBuffer(_toSign)).then(function(match) { var verT = document.createElement('h2') verT.innerHTML = 'Outcome:' document.querySelector('body').appendChild(verT) var divOut = document.createElement('div') divOut.innerHTML = (match)?'Success':'Failed'; document.querySelector('body').appendChild(divOut) }) }) // load keys and re-check signature importPublicKey(keys.publicKey).then(function(key) { testVerifySig(key, _signedData, textToArrayBuffer(_toSign)).then(function(match) { console.log("Signature verified after importing PEM public key:", match) }) }) // should output `Signature verified: true` twice in the console }) }) } -
Andrei revised this gist
Mar 20, 2015 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -157,7 +157,7 @@ if (crypto.subtle) { testVerifySig(pair.publicKey, signedData, textToArrayBuffer(_toSign)); }); // load keys and re-check signature importPublicKey(keys.publicKey).then(function(key) { testVerifySig(key, _signedData, textToArrayBuffer(_toSign)); }); -
Andrei revised this gist
Mar 14, 2015 . 1 changed file with 9 additions and 11 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -31,7 +31,6 @@ function arrayBufferToBase64String(arrayBuffer) { return btoa(byteString); } function base64StringToArrayBuffer(b64str) { var byteStr = atob(b64str); var bytes = new Uint8Array(byteStr.length); @@ -144,24 +143,23 @@ function testVerifySig(pub, sig, data) { }); } // Test everything var crypto = window.crypto || window.msCrypto; if (crypto.subtle) { var _signedData; var _toSign = "test"; generateRSAKey().then(function(pair) { exportPemKeys(pair).then(function(keys) { // signData returns an ArrayBuffer; use arraySignatureToBase64() to see the value signData(pair.privateKey, _toSign).then(function(signedData) { // console.log(arraySignatureToBase64(result)); _signedData = signedData; testVerifySig(pair.publicKey, signedData, textToArrayBuffer(_toSign)); }); // load keys and recheck signature importPublicKey(keys.publicKey).then(function(key) { testVerifySig(key, _signedData, textToArrayBuffer(_toSign)); }); // should output `Signature verified: true` twice in the console }); -
Andrei renamed this gist
Mar 14, 2015 . 1 changed file with 1 addition and 4 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -125,10 +125,7 @@ function exportPrivateKey(keys) { function exportPemKeys(keys) { return new Promise(function(resolve) { exportPublicKey(keys).then(function(pubKey) { exportPrivateKey(keys).then(function(privKey) { resolve({publicKey: pubKey, privateKey: privKey}); }); }); @@ -148,7 +145,7 @@ function testVerifySig(pub, sig, data) { } // Do some crypto tests var crypto = window.crypto || window.msCrypto; if (crypto.subtle) { var keys, signed; -
Andrei revised this gist
Mar 14, 2015 . No changes.There are no files selected for viewing
-
Andrei revised this gist
Mar 14, 2015 . No changes.There are no files selected for viewing
-
Andrei revised this gist
Mar 14, 2015 . No changes.There are no files selected for viewing
-
Andrei revised this gist
Mar 14, 2015 . 1 changed file with 34 additions and 24 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -86,6 +86,24 @@ function convertPemToBinary(pem) { return base64StringToArrayBuffer(encoded); } function importPublicKey(pemKey) { return new Promise(function(resolve) { var importer = crypto.subtle.importKey("spki", convertPemToBinary(pemKey), signAlgorithm, true, ["verify"]); importer.then(function(key) { resolve(key); }); }); } function importPrivateKey(pemKey) { return new Promise(function(resolve) { var importer = crypto.subtle.importKey("pkcs8", convertPemToBinary(pemKey), signAlgorithm, true, ["sign"]); importer.then(function(key) { resolve(key); }); }); } function exportPublicKey(keys) { return new Promise(function(resolve) { window.crypto.subtle.exportKey('spki', keys.publicKey). @@ -104,7 +122,7 @@ function exportPrivateKey(keys) { }); } function exportPemKeys(keys) { return new Promise(function(resolve) { exportPublicKey(keys).then(function(pubKey) { document.getElementById("pem-public-key").innerText = pubKey; @@ -124,39 +142,31 @@ function signData(key, data) { } function testVerifySig(pub, sig, data) { return crypto.subtle.verify(signAlgorithm, pub, sig, data).then(function(match) { console.log("Signature verified: "+match); }); } // Do the crypto goodness var crypto = window.crypto || window.msCrypto; if (crypto.subtle) { var keys, signed; var toSign = "test"; generateRSAKey().then(function(pair) { exportPemKeys(pair).then(function(keys) { // signData returns an ArrayBuffer; used arraySignatureToBase64() to see the value signData(pair.privateKey, toSign).then(function(result) { // console.log(arraySignatureToBase64(result)); signed = result; testVerifySig(pair.publicKey, result, textToArrayBuffer(toSign)); }); // load keys and recheck sig importPublicKey(keys.publicKey).then(function(key) { testVerifySig(key, signed, textToArrayBuffer(toSign)); }); // should output `Signature verified: true` twice in the console }); }); } -
Andrei revised this gist
Mar 14, 2015 . No changes.There are no files selected for viewing
-
Andrei created this gist
Mar 14, 2015 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,162 @@ var signAlgorithm = { name: "RSASSA-PKCS1-v1_5", hash: { name: "SHA-256" } } function generateRSAKey() { var alg = { name: "RSASSA-PKCS1-v1_5", hash: {name: "SHA-256"}, modulusLength: 2048, extractable: true, publicExponent: new Uint8Array([1, 0, 1]) }; return new Promise(function(resolve) { var genkey = crypto.subtle.generateKey(alg, true, ["sign", "verify"]); genkey.then(function (pair) { resolve(pair); }); }); } function arrayBufferToBase64String(arrayBuffer) { var byteArray = new Uint8Array(arrayBuffer) var byteString = ''; for (var i=0; i<byteArray.byteLength; i++) { byteString += String.fromCharCode(byteArray[i]); } return btoa(byteString); } function base64StringToArrayBuffer(b64str) { var byteStr = atob(b64str); var bytes = new Uint8Array(byteStr.length); for (var i = 0; i < byteStr.length; i++) { bytes[i] = byteStr.charCodeAt(i); } return bytes.buffer; } function textToArrayBuffer(str) { var buf = unescape(encodeURIComponent(str)); // 2 bytes for each char var bufView = new Uint8Array(buf.length); for (var i=0; i < buf.length; i++) { bufView[i] = buf.charCodeAt(i); } return bufView; } function arraySignatureToBase64(arr) { return btoa(String.fromCharCode.apply(null, new Uint8Array(arr))); } function convertBinaryToPem(binaryData, label) { var base64Cert = arrayBufferToBase64String(binaryData); var pemCert = "-----BEGIN " + label + "-----\r\n"; var nextIndex = 0; var lineLength; while (nextIndex < base64Cert.length) { if (nextIndex + 64 <= base64Cert.length) { pemCert += base64Cert.substr(nextIndex, 64) + "\r\n"; } else { pemCert += base64Cert.substr(nextIndex) + "\r\n"; } nextIndex += 64; } pemCert += "-----END " + label + "-----\r\n"; return pemCert; } function convertPemToBinary(pem) { var lines = pem.split('\n'); var encoded = ''; for(var i = 0;i < lines.length;i++){ if (lines[i].trim().length > 0 && lines[i].indexOf('-BEGIN RSA PRIVATE KEY-') < 0 && lines[i].indexOf('-BEGIN RSA PUBLIC KEY-') < 0 && lines[i].indexOf('-END RSA PRIVATE KEY-') < 0 && lines[i].indexOf('-END RSA PUBLIC KEY-') < 0) { encoded += lines[i].trim(); } } return base64StringToArrayBuffer(encoded); } function exportPublicKey(keys) { return new Promise(function(resolve) { window.crypto.subtle.exportKey('spki', keys.publicKey). then(function(spki) { resolve(convertBinaryToPem(spki, "RSA PUBLIC KEY")); }); }); } function exportPrivateKey(keys) { return new Promise(function(resolve) { var expK = window.crypto.subtle.exportKey('pkcs8', keys.privateKey); expK.then(function(pkcs8) { resolve(convertBinaryToPem(pkcs8, "RSA PRIVATE KEY")); }); }); } function exportKeys(keys) { return new Promise(function(resolve) { exportPublicKey(keys).then(function(pubKey) { document.getElementById("pem-public-key").innerText = pubKey; exportPrivateKey(keys).then(function(privKey) { document.getElementById("pem-private-key").innerText = privKey; resolve({publicKey: pubKey, privateKey: privKey}); }); }); }); } function signData(key, data) { var buffer = textToArrayBuffer(data); console.log(); return window.crypto.subtle.sign(signAlgorithm, key, buffer); } function testVerifySig(pub, sig, data) { return crypto.subtle.verify(signAlgorithm, pub, sig, data); } // Do the crypto goodness var crypto = window.crypto || window.msCrypto; if (crypto.subtle) { var keys, signed, __pkey; generateRSAKey().then(function(pair) { console.log("Pair: ", pair); exportKeys(pair).then(function(keys) { // console.log(keys); // sign signData(pair.privateKey, "test").then(function(result) { console.log(arraySignatureToBase64(result)); signed = result; testVerifySig(pair.publicKey, result, textToArrayBuffer("test")).then(function(verdict) { console.log("Signature verified: "+verdict); }); }); // load keys and check sig var parsedPEM = convertPemToBinary(keys.publicKey); crypto.subtle.importKey("spki", parsedPEM, signAlgorithm, true, ["verify"]). then(function(key) { __pkey = key; console.log("Parsed key", key); testVerifySig(key, signed, textToArrayBuffer("test")).then(function(verdict) { console.log("Signature verified again: "+verdict); }); }); }); }); }