Files @ 64020ac8e211
Branch filter:

Location: CryptoJS/src/main.js

Laman
added key stretching with PBKDF2
import * as util from "./util.js";
import {blake2s} from "./blake.js";
import {pbkdf2} from "./pbkdf2.js";
import {createNonce,Chacha20,encrypt as _encrypt,decrypt as _decrypt} from "./chacha.js";

const VERSION=1;

function encrypt(s,password){
	let bs=util.str2utf8(s);
	let pass=util.str2utf8(password);
	let salt=createNonce();
	let [iters,key]=stretchKey(pass,salt);
	let noncedCiphertext=_encrypt(bs,key,salt);
	let payload=[iters].concat(noncedCiphertext);
	let signature=blake2s([VERSION].concat(payload),16,pass);
	let arr=[VERSION].concat(signature,payload);
	return util.bytes2base64(arr);
}

function decrypt(s,password){
	let pass=util.str2utf8(password);
	let arr=util.base642bytes(s);
	let version=arr[0];
	let signature=arr.slice(1,17);
	let iters=arr[17];
	let salt=arr.slice(18,30);
	let noncedCiphertext=arr.slice(18);
	let check=blake2s([version].concat([iters],noncedCiphertext),16,pass);
	if(!signature.every((b,i)=>b===check[i])){return false;}
	if(version>VERSION){return false;}
	let key=pbkdf2(pass,salt,1<<iters,32);
	let plainbytes=_decrypt(noncedCiphertext,key);
	return util.utf82str(plainbytes);
}

function stretchKey(password,salt){
	let start=Date.now(); // ms
	let i,key;
	for(i=0;i<256;i++){
		key=pbkdf2(password,salt,1<<i,32);
		if(Date.now()-start>=500){break;}
	}
	return [i,key];
}

export default {util,blake2s,pbkdf2,Chacha20,encrypt,decrypt};

// export for tests running on Node
if(typeof module!=='undefined'&&module.hasOwnProperty('exports')){
	module.exports.util=util;
	module.exports.blake2s=blake2s;
	module.exports.pbkdf2=pbkdf2;
	module.exports.Chacha20=Chacha20;
	module.exports.encrypt=_encrypt;
	module.exports.decrypt=_decrypt;
}