walnut.js/lib/com.daplie.walnut.current/scripts/pbkdf2.webcrypto.test.js

77 lines
2.5 KiB
JavaScript

(function () {
'use strict';
var crypto = window.crypto;
var Unibabel = window.Unibabel;
function deriveKey(saltHex, passphrase, iter) {
var keyLenBits = 128;
var kdfname = "PBKDF2";
var aesname = "AES-CBC"; // AES-CTR is also popular
// 100 - probably safe even on a browser running from a raspberry pi using pure js ployfill
// 10000 - no noticeable speed decrease on my MBP
// 100000 - you can notice
// 1000000 - annoyingly long
var iterations = iter || 100; // something a browser on a raspberry pi or old phone could do
var hashname = "SHA-256";
var extractable = true;
console.log('');
console.log('passphrase', passphrase);
console.log('salt (hex)', saltHex);
//console.log('salt (hex)', Unibabel.bufferToHex(saltBuf));
console.log('iterations', iterations);
console.log('keyLen (bytes)', keyLenBits / 8);
console.log('digest', hashname);
// First, create a PBKDF2 "key" containing the password
return crypto.subtle.importKey(
"raw"
, Unibabel.utf8ToBuffer(passphrase)
, { "name": kdfname }
, false
, ["deriveKey"]).
// Derive a key from the password
then(function (passphraseKey) {
return crypto.subtle.deriveKey(
{ "name": kdfname
, "salt": Unibabel.hexToBuffer(saltHex)
, "iterations": iterations
, "hash": hashname
}
, passphraseKey
// required to be 128 or 256 bits
, { "name": aesname, "length": keyLenBits } // Key we want
, extractable // Extractble
, [ "encrypt", "decrypt" ] // For new key
);
}).
// Export it so we can display it
then(function (aesKey) {
return crypto.subtle.exportKey("raw", aesKey).then(function (arrbuf) {
return new Uint8Array(arrbuf);
});
}).
catch(function (err) {
window.alert("Key derivation failed: " + err.message);
});
}
function test() {
// Part of the salt is application-specific (same on iOS, Android, and Web)
var saltHex = '942c2db750b5f57f330226b2b498c6d3';
var passphrase = 'Pizzas are like children';
//var passphrase = "I'm a ☢ ☃ who speaks 中国语文!";
var iter = 1672;
// NOTE: the salt will be truncated to the length of the hash algo being used
return deriveKey(saltHex, passphrase, iter).then(function (keyBuf) {
var hexKey = Unibabel.bufferToHex(keyBuf);
console.log('[TEST] hexKey');
console.log(hexKey);
});
}
test();
}());