Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Sam7 js encryption
function pbkdf_aes_key(aes, pObj) {
var pidcrypt = aes.pidcrypt;
var retObj = {};
var count = 1;
var miter = 3;
if(!pObj) pObj = {};
if(pObj.rounds) {
count = pObj.rounds;
}
if(!pObj.salt) {
pObj.salt = pidcrypt.getRandomBytes(8);
pObj.salt = pidCryptUtil.convertToHex(pidCryptUtil.byteArray2String(pObj.salt));
pidcrypt.setParams({salt: pObj.salt});
}
var pass = pObj.password;
if (typeof pass != "string") {
pass = pidCryptUtil.byteArray2String(pass);
}
var data00 = pass + pidCryptUtil.convertFromHex(pObj.salt);
var hashtarget = '';
var result = '';
var keymaterial = '';
var loop = 0;
keymaterial[loop++] = data00;
for(var j=0; j<miter; j++){
result = result + data00;
result = pidCryptUtil.toByteArray(result);
for(var c=0; c<count; c++){
result = Crypto.SHA256(result, {asBytes: true});
}
result = pidCryptUtil.byteArray2String(result);
keymaterial += result;
}
switch(pObj.bits){
case 128://128 bit
retObj.key = pidCryptUtil.convertToHex(keymaterial.slice(0, 16));
retObj.iv = pidCryptUtil.convertToHex(keymaterial.slice(16, 32));
break;
case 192://192 bit
retObj.key = pidCryptUtil.convertToHex(keymaterial.slice(0, 24));
retObj.iv = pidCryptUtil.convertToHex(keymaterial.slice(24, 40));
break;
case 256://256 bit
retObj.key = pidCryptUtil.convertToHex(keymaterial.slice(0, 32));
retObj.iv = pidCryptUtil.convertToHex(keymaterial.slice(32, 48));
break;
default:
pidcrypt.appendError('get_aes_key: Sorry, only 128, 192 and 256 bits are supported.\nBits('+typeof(pObj.bits)+') = '+pObj.bits);
}
return retObj;
}
function aes_encrypt_raw_nopadding(aescbc, byteArray) {
var pidcrypt = aescbc.pidcrypt;
var aes = aescbc.aes;
var p = pidcrypt.getParams(); //get parameters for operation set by init
if(!byteArray)
byteArray = p.encryptIn;
pidcrypt.setParams({encryptIn: byteArray});
if(!p.dataIn) pidcrypt.setParams({dataIn:byteArray});
var iv = pidCryptUtil.convertFromHex(p.iv);
var charDiv = (byteArray.length % p.blockSize);
if (charDiv > 0) {
charDiv = p.blockSize - charDiv;
}
for(var c=0;c<charDiv;c++) byteArray[byteArray.length] = charDiv;
var nBytes = Math.floor(p.nBits/8); // nr of bytes in key
var keyBytes = new Array(nBytes);
var key = pidCryptUtil.convertFromHex(p.key);
for (var i=0; i<nBytes; i++) {
keyBytes[i] = isNaN(key.charCodeAt(i)) ? 0 : key.charCodeAt(i);
}
// generate key schedule
var keySchedule = aes.expandKey(keyBytes);
var blockCount = Math.ceil(byteArray.length/p.blockSize);
var ciphertxt = new Array(blockCount); // ciphertext as array of strings
var textBlock = [];
var state = pidCryptUtil.toByteArray(iv);
for (var b=0; b<blockCount; b++) {
// XOR last block and next data block, then encrypt that
textBlock = byteArray.slice(b*p.blockSize, b*p.blockSize+p.blockSize);
state = aes.xOr_Array(state, textBlock);
state = aes.encrypt(state.slice(), keySchedule); // -- encrypt block --
ciphertxt[b] = pidCryptUtil.byteArray2String(state);
}
var ciphertext = ciphertxt.join('');
pidcrypt.setParams({dataOut:ciphertext, encryptOut:ciphertext});
if(!pidcrypt.isDebug() && pidcrypt.clear) pidcrypt.clearParams();
return ciphertext || '';
}
function aes_decrypt_raw_nopadding(aescbc, byteArray) {
var aes = aescbc.aes;
var pidcrypt = aescbc.pidcrypt;
var p = pidcrypt.getParams(); //get parameters for operation set by init
if(!byteArray)
byteArray = p.decryptIn;
pidcrypt.setParams({decryptIn: byteArray});
if(!p.dataIn) pidcrypt.setParams({dataIn:byteArray});
if((p.iv.length/2)<p.blockSize)
return pidcrypt.appendError('pidCrypt.AES.CBC.decrypt: Sorry, can not decrypt without complete set of parameters.\n Length of key,iv:'+p.key.length+','+p.iv.length);
var iv = pidCryptUtil.convertFromHex(p.iv);
if(byteArray.length%p.blockSize != 0)
return pidcrypt.appendError('pidCrypt.AES.CBC.decrypt: Sorry, the encrypted text has the wrong length for aes-cbc mode\n Length of ciphertext:'+byteArray.length+byteArray.length%p.blockSize);
var nBytes = Math.floor(p.nBits/8); // nr of bytes in key
var keyBytes = new Array(nBytes);
var key = pidCryptUtil.convertFromHex(p.key);
for (var i=0; i<nBytes; i++) {
keyBytes[i] = isNaN(key.charCodeAt(i)) ? 0 : key.charCodeAt(i);
}
// generate key schedule
var keySchedule = aes.expandKey(keyBytes);
// separate byteArray into blocks
var nBlocks = Math.ceil((byteArray.length) / p.blockSize);
// plaintext will get generated block-by-block into array of block-length strings
var plaintxt = new Array(nBlocks.length);
var state = pidCryptUtil.toByteArray(iv);
var ciphertextBlock = [];
var dec_state = [];
for (var b=0; b<nBlocks; b++) {
ciphertextBlock = byteArray.slice(b*p.blockSize, b*p.blockSize+p.blockSize);
dec_state = aes.decrypt(ciphertextBlock, keySchedule); // decrypt ciphertext block
plaintxt[b] = pidCryptUtil.byteArray2String(aes.xOr_Array(state, dec_state));
state = ciphertextBlock.slice(); //save old ciphertext for next round
}
// join array of blocks into single plaintext string and return it
var plaintext = plaintxt.join('');
pidcrypt.setParams({dataOut: plaintext,decryptOut: plaintext});
//remove all parameters from enviroment for more security is debug off
if(!pidcrypt.isDebug() && pidcrypt.clear) pidcrypt.clearParams();
return plaintext || '';
}
function b58_encode_check(value_bytes) {
var checksum = Crypto.SHA256(Crypto.SHA256(value_bytes, {asBytes: true}),
{asBytes: true});
value_bytes = value_bytes.concat(checksum.slice(0, 4));
return Bitcoin.Base58.encode(value_bytes);
}
function b58_decode_check(value_b58) {
var value_bytes = Bitcoin.Base58.decode(value_b58);
if (value_bytes.length < 5) {
return [];
}
var checksum = Crypto.SHA256(
Crypto.SHA256(value_bytes.slice(0, value_bytes.length - 4),
{asBytes: true}),
{asBytes: true});
if ((value_bytes[value_bytes.length - 4] != checksum[0]) ||
(value_bytes[value_bytes.length - 3] != checksum[1]) ||
(value_bytes[value_bytes.length - 2] != checksum[2]) ||
(value_bytes[value_bytes.length - 1] != checksum[3])) {
return [];
}
return value_bytes.slice(0, value_bytes.length - 4);
}
function protected_privkey_encode(privkey_b58, password) {
var privkey = b58_decode_check(privkey_b58);
if (!privkey || (privkey.length != 33) || (privkey[0] != 128))
return "Invalid private key";
password = pidCryptUtil.encodeUTF8(password) + "\0";
var pbkdfParam = {password:password, rounds:4096, bits:256};
var aes = new pidCrypt.AES.CBC();
// Use four bytes of salt instead of the PBKDF recommended 8
salt_bytes = aes.pidcrypt.getRandomBytes(4).concat([0x7f,0x7f,0x7f,0x7f]);
pbkdfParam.salt = pidCryptUtil.convertToHex(
pidCryptUtil.byteArray2String(salt_bytes));
var params = pbkdf_aes_key(aes, pbkdfParam);
aes.pidcrypt.setParams(params);
aes.aes.init();
var salt_bytes = pidCryptUtil.toByteArray(
pidCryptUtil.convertFromHex(pbkdfParam.salt));
var protected_privkey = aes_encrypt_raw_nopadding(aes, privkey.slice(1));
protected_privkey = pidCryptUtil.toByteArray(protected_privkey);
var check_subject = privkey.slice(1).concat(salt_bytes);
var plain_checksum = Crypto.SHA256(
Crypto.SHA256(check_subject, {asBytes: true}),
{asBytes: true});
var protkey = [136];
protkey = protkey.concat(protected_privkey);
protkey = protkey.concat(plain_checksum.slice(0, 8));
protkey = protkey.concat(salt_bytes.slice(0, 4));
return b58_encode_check(protkey);
}
function protected_privkey_decode(protkey_b58, password) {
var protkey = b58_decode_check(protkey_b58);
if (!protkey || (protkey.length != 45) || (protkey[0] != 136))
return "Invalid protected private key";
password = pidCryptUtil.encodeUTF8(password) + "\0";
var protected_privkey = protkey.slice(1, 33);
var expect_checksum = protkey.slice(33, 41);
var salt_bytes = protkey.slice(41, 45).concat([0x7f,0x7f,0x7f,0x7f]);
var pbkdfParam = {password:password, rounds:4096, bits:256};
pbkdfParam.salt = pidCryptUtil.convertToHex(
pidCryptUtil.byteArray2String(salt_bytes));
var aes = new pidCrypt.AES.CBC();
var params = pbkdf_aes_key(aes, pbkdfParam);
aes.pidcrypt.setParams(params);
aes.aes.init();
var privkey_str = aes_decrypt_raw_nopadding(aes, protected_privkey);
privkey = [128].concat(pidCryptUtil.toByteArray(privkey_str));
var check_subject = privkey.slice(1).concat(salt_bytes);
var plain_checksum = Crypto.SHA256(
Crypto.SHA256(check_subject, {asBytes: true}),
{asBytes: true});
var i;
for (i = 0; i < 8; i++) {
if (plain_checksum[i] != expect_checksum[i])
return "Invalid password";
}
return b58_encode_check(privkey);
}
function do_form_protect_key() {
var privkey_b58 = document.getElementById("privkey-in").value;
var password = document.getElementById("prot-password-in").value;
document.getElementById("protkey-out").innerHTML =
protected_privkey_encode(privkey_b58, password);
}
function do_form_unprotect_key() {
var privkey_b58 = document.getElementById("protkey-in").value;
var password = document.getElementById("unprot-password-in").value;
document.getElementById("privkey-out").innerHTML =
protected_privkey_decode(privkey_b58, password);
}
@mkvtvseries

This comment has been minimized.

Copy link

commented Jan 26, 2018

Hello, How to run on browser? Please help

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.