source/web/HashingTools.js
function deriveKeyFromPassword(password, salt, rounds, bits) {
    checkBrowserSupport();
    const subtleCrypto = window.crypto.subtle;
    let params = {
            name: "PBKDF2",
            hash: "SHA-256",
            salt: stringToArrayBuffer(salt),
            iterations: rounds
        },
        bytes = bits / 8,
        keysLen = bytes / 2;
    return subtleCrypto
        .importKey(
            "raw",
            stringToArrayBuffer(password),
            { name: "PBKDF2" },
            false, // not extractable
            ["deriveBits"]
        )
        .then(keyData => subtleCrypto.deriveBits(params, keyData, bits))
        .then(derivedData =>
            Promise.all([
                subtleCrypto.importKey("raw", derivedData.slice(0, keysLen), "AES-CBC", true, ["encrypt", "decrypt"]),
                subtleCrypto.importKey("raw", derivedData.slice(keysLen, keysLen * 2), "AES-CBC", true, [
                    "encrypt",
                    "decrypt"
                ])
            ])
        )
        .then(aesKeys =>
            Promise.all([subtleCrypto.exportKey("raw", aesKeys[0]), subtleCrypto.exportKey("raw", aesKeys[1])])
        )
        .then(rawKeys => joinBuffers(rawKeys[0], rawKeys[1]))
        .then(arrBuff => addHexSupportToArrayBuffer(arrBuff)); // HAXOR
}
function deriveKeyFromPassword(password, salt, rounds, bits) {
    checkBrowserSupport();
    const subtleCrypto = window.crypto.subtle;
    let params = {
            name: "PBKDF2",
            hash: "SHA-256",
            salt: stringToArrayBuffer(salt),
            iterations: rounds
        },
        bytes = bits / 8,
        keysLen = bytes / 2;
    return subtleCrypto
        .importKey(
            "raw",
            stringToArrayBuffer(password),
            { name: "PBKDF2" },
            false, // not extractable
            ["deriveBits"]
        )
        .then(keyData => subtleCrypto.deriveBits(params, keyData, bits))
        .then(derivedData =>
            Promise.all([
                subtleCrypto.importKey("raw", derivedData.slice(0, keysLen), "AES-CBC", true, ["encrypt", "decrypt"]),
                subtleCrypto.importKey("raw", derivedData.slice(keysLen, keysLen * 2), "AES-CBC", true, [
                    "encrypt",
                    "decrypt"
                ])
            ])
        )
        .then(aesKeys =>
            Promise.all([subtleCrypto.exportKey("raw", aesKeys[0]), subtleCrypto.exportKey("raw", aesKeys[1])])
        )
        .then(rawKeys => joinBuffers(rawKeys[0], rawKeys[1]))
        .then(arrBuff => addHexSupportToArrayBuffer(arrBuff)); // HAXOR
}
function deriveKeyFromPassword ( password , salt , rounds , bits ) { checkBrowserSupport ( ) ; const subtleCrypto = window . crypto . subtle ; let params = { name : "PBKDF2" , hash : "SHA-256" , salt : stringToArrayBuffer ( salt ) , iterations : rounds } , bytes = bits / 8 , keysLen = bytes / 2 ; return subtleCrypto . importKey ( "raw" , stringToArrayBuffer ( password ) , { name : "PBKDF2" } , false , // not extractable [ "deriveBits" ] ) . then ( keyData => subtleCrypto . deriveBits ( params , keyData , bits ) ) . then ( derivedData => Promise . all ( [ subtleCrypto . importKey ( "raw" , derivedData . slice ( 0 , keysLen ) , "AES-CBC" , true , [ "encrypt" , "decrypt" ] ) , subtleCrypto . importKey ( "raw" , derivedData . slice ( keysLen , keysLen * 2 ) , "AES-CBC" , true , [ "encrypt" , "decrypt" ] ) ] ) ) . then ( aesKeys => Promise . all ( [ subtleCrypto . exportKey ( "raw" , aesKeys [ 0 ] ) , subtleCrypto . exportKey ( "raw" , aesKeys [ 1 ] ) ] ) ) . then ( rawKeys => joinBuffers ( rawKeys [ 0 ] , rawKeys [ 1 ] ) ) . then ( arrBuff => addHexSupportToArrayBuffer ( arrBuff ) ) ; // HAXOR }
Derive a key from a password
@param {String} password The password
@param {String} salt The salt
@param {Number} rounds The number of derivation rounds
@param {Number} bits The number of bits for the key
@see checkBrowserSupport
@returns {Promise.<ArrayBuffer>} A promise that resolves with an ArrayBuffer
Derive a key from a password