dtl-js
Version:
Data Transformation Language - JSON templates and data transformation
137 lines (126 loc) • 4.83 kB
JavaScript
/* =================================================
* Copyright (c) 2015-2022 Jay Kuri
*
* This file is part of DTL.
*
* DTL is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* DTL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with DTL; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* =================================================
*/
const crypto = require("crypto");
const md5 = require("./md5.js");
const algorithms = {
"sha1": "SHA-1",
"sha256": "SHA-256",
"sha512": "SHA-512"
}
function calculate_hash(method, data) {
let bytes = data;
if(typeof data == 'string') {
bytes = new TextEncoder().encode(data);
}
if (typeof crypto.createHash == 'function') {
return node_crypto_hash(method, data);
} else {
throw new Error('This DTL build does not include access to crypto functions.');
}
}
function node_crypto_hash(method, data) {
let hash = crypto.createHash(method);
return hash.update(data).digest('hex');
}
const default_scrypt_options = {
N: 32768,
maxmem: 64 * 1024 * 1024
};
function normalize_scrypt_settings(keylen, options) {
let derived_key_length = keylen;
let scrypt_options = options;
if (typeof derived_key_length == 'object' && derived_key_length !== null && typeof scrypt_options == 'undefined') {
scrypt_options = derived_key_length;
derived_key_length = undefined;
}
if (typeof derived_key_length == 'undefined' || derived_key_length === null) {
derived_key_length = 64;
}
if (typeof scrypt_options == 'undefined' || scrypt_options === null) {
scrypt_options = {};
}
scrypt_options = Object.assign({}, default_scrypt_options, scrypt_options);
if (typeof scrypt_options.cost == 'number' && typeof scrypt_options.N == 'undefined') {
scrypt_options.N = scrypt_options.cost;
}
return {
keylen: derived_key_length,
options: scrypt_options
};
}
function calculate_scrypt(password, salt, keylen, options) {
if (typeof crypto.scryptSync == 'function') {
return node_crypto_scrypt(password, salt, keylen, options);
} else {
throw new Error('This DTL build does not include access to scrypt functions.');
}
}
function node_crypto_scrypt(password, salt, keylen, options) {
let settings = normalize_scrypt_settings(keylen, options);
let derived_key = crypto.scryptSync(password, salt, settings.keylen, settings.options);
return derived_key.toString('hex');
}
let helper_list = {
'hash': {
'meta': {
'syntax': 'hash( $method $data )',
'returns': 'A hash of the provided data using $method',
'description': [
'Returns a hash of the provided $data using $method. Supported methods are ',
'SHA1, SHA256, SHA512, and MD5. Note that by default the browser version ',
'only includes md5. See https://gitlab.com/jk0ne/DTL/-/issues/9 for details.'
]
},
'*': function(method, data) {
try {
let hash = calculate_hash(method, data);
return hash;
} catch (e) {
console.warn("Failed creating hash: " + e);
return undefined;
}
},
},
'scrypt': {
'meta': {
'syntax': 'scrypt( $password $salt [$keylen] [$options] )',
'returns': 'A derived key created with scrypt',
'description': [
'Returns a derived key using scrypt with the provided $password, $salt, and $keylen. ',
'Defaults to a 64-byte key length with N=32768 and maxmem=64MB. ',
'This helper is only available in node builds with crypto support. The result is hex encoded.'
]
},
'*': function(password, salt, keylen, options) {
try {
let derived_key = calculate_scrypt(password, salt, keylen, options);
return derived_key;
} catch (e) {
console.warn("Failed creating scrypt hash: " + e);
return undefined;
}
},
}
};
function dtl_crypto_helpers() {
return helper_list;
}
module.exports = dtl_crypto_helpers;