|
|
|
async function encryptDataSaveKey() { |
|
var data = await makeData(); |
|
console.log("generated data", data); |
|
var keys = await makeKeys() |
|
var encrypted = await encrypt(data, keys); |
|
callOnStore(function (store) { |
|
store.put({id: 1, keys: keys, encrypted: encrypted}); |
|
}) |
|
} |
|
|
|
function loadKeyDecryptData() { |
|
callOnStore(function (store) { |
|
var getData = store.get(1); |
|
getData.onsuccess = async function() { |
|
var keys = getData.result.keys; |
|
var encrypted = getData.result.encrypted; |
|
var data = await decrypt(encrypted, keys); |
|
console.log("decrypted data", data); |
|
}; |
|
}) |
|
} |
|
|
|
function callOnStore(fn_) { |
|
|
|
// This works on all devices/browsers, and uses IndexedDBShim as a final fallback |
|
var indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB || window.shimIndexedDB; |
|
|
|
// Open (or create) the database |
|
var open = indexedDB.open("MyDatabase", 1); |
|
|
|
// Create the schema |
|
open.onupgradeneeded = function() { |
|
var db = open.result; |
|
var store = db.createObjectStore("MyObjectStore", {keyPath: "id"}); |
|
}; |
|
|
|
|
|
open.onsuccess = function() { |
|
// Start a new transaction |
|
var db = open.result; |
|
var tx = db.transaction("MyObjectStore", "readwrite"); |
|
var store = tx.objectStore("MyObjectStore"); |
|
|
|
fn_(store) |
|
|
|
|
|
// Close the db when the transaction is done |
|
tx.oncomplete = function() { |
|
db.close(); |
|
}; |
|
} |
|
} |
|
|
|
async function encryptDecrypt() { |
|
var data = await makeData(); |
|
console.log("generated data", data); |
|
var keys = await makeKeys() |
|
var encrypted = await encrypt(data, keys); |
|
console.log("encrypted", encrypted); |
|
var finalData = await decrypt(encrypted, keys); |
|
console.log("decrypted data", data); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
function makeData() { |
|
return window.crypto.getRandomValues(new Uint8Array(16)) |
|
} |
|
|
|
function makeKeys() { |
|
return window.crypto.subtle.generateKey( |
|
{ |
|
name: "RSA-OAEP", |
|
modulusLength: 2048, //can be 1024, 2048, or 4096 |
|
publicExponent: new Uint8Array([0x01, 0x00, 0x01]), |
|
hash: {name: "SHA-256"}, //can be "SHA-1", "SHA-256", "SHA-384", or "SHA-512" |
|
}, |
|
false, //whether the key is extractable (i.e. can be used in exportKey) |
|
["encrypt", "decrypt"] //must be ["encrypt", "decrypt"] or ["wrapKey", "unwrapKey"] |
|
) |
|
} |
|
|
|
function encrypt(data, keys) { |
|
return window.crypto.subtle.encrypt( |
|
{ |
|
name: "RSA-OAEP", |
|
//label: Uint8Array([...]) //optional |
|
}, |
|
keys.publicKey, //from generateKey or importKey above |
|
data //ArrayBuffer of data you want to encrypt |
|
) |
|
} |
|
|
|
|
|
async function decrypt(data, keys) { |
|
return new Uint8Array(await window.crypto.subtle.decrypt( |
|
{ |
|
name: "RSA-OAEP", |
|
//label: Uint8Array([...]) //optional |
|
}, |
|
keys.privateKey, //from generateKey or importKey above |
|
data //ArrayBuffer of the data |
|
)); |
|
} |