|
| 1 | +// HELP ME MAKE THIS SHITTY CIPHER API GREAT AGAIN // |
| 2 | + |
| 3 | +crypto = require('crypto'); |
| 4 | + |
| 5 | +function randomValueHex (len) { |
| 6 | + return crypto.randomBytes(Math.ceil(len/2)) |
| 7 | + .toString('hex') // convert to hexadecimal format |
| 8 | + .slice(0,len); // return required number of characters |
| 9 | +}; |
| 10 | + |
| 11 | +var key1, ALGORITHM, KEY, HMAC_ALGORITHM, HMAC_KEY; |
| 12 | + |
| 13 | +ALGORITHM = 'AES-256-CBC'; // CBC because CTR isn't possible with the current version of the Node.JS crypto library |
| 14 | +HMAC_ALGORITHM = 'SHA256'; |
| 15 | +KEY = randomValueHex(32); // This key should be stored in an environment variable |
| 16 | +HMAC_KEY = randomValueHex(32); // This key should be stored in an environment variable |
| 17 | + |
| 18 | +var constant_time_compare = function (val1, val2) { |
| 19 | + var sentinel; |
| 20 | + |
| 21 | + if (val1.length !== val2.length) { |
| 22 | + return false; |
| 23 | + } |
| 24 | + |
| 25 | + |
| 26 | + for (var i = 0; i <= (val1.length - 1); i++) { |
| 27 | + sentinel |= val1.charCodeAt(i) ^ val2.charCodeAt(i); |
| 28 | + } |
| 29 | + |
| 30 | + return sentinel === 0 |
| 31 | +}; |
| 32 | + |
| 33 | +module.exports = { |
| 34 | + |
| 35 | + "enc": { |
| 36 | + run : function (plain_text) { |
| 37 | + |
| 38 | + var IV = new Buffer(randomValueHex(16)); // ensure that the IV (initialization vector) is random |
| 39 | + var cipher_text; |
| 40 | + var hmac; |
| 41 | + var encryptor; |
| 42 | + |
| 43 | + encryptor = crypto.createCipheriv(ALGORITHM, KEY, IV); |
| 44 | + encryptor.setEncoding('hex'); |
| 45 | + encryptor.write(plain_text); |
| 46 | + encryptor.end(); |
| 47 | + |
| 48 | + cipher_text = encryptor.read(); |
| 49 | + |
| 50 | + hmac = crypto.createHmac(HMAC_ALGORITHM, HMAC_KEY); |
| 51 | + hmac.update(cipher_text); |
| 52 | + hmac.update(IV.toString('hex')); // ensure that both the IV and the cipher-text is protected by the HMAC |
| 53 | + |
| 54 | + // The IV isn't a secret so it can be stored along side everything else |
| 55 | + return cipher_text + "$" + IV.toString('hex') + "$" + hmac.digest('hex') |
| 56 | + } |
| 57 | + }, |
| 58 | + |
| 59 | + "dec": { |
| 60 | + run : function (cipher_text) { |
| 61 | + var cipher_blob = cipher_text.split("$"); |
| 62 | + var ct = cipher_blob[0]; |
| 63 | + var IV = new Buffer(cipher_blob[1], 'hex'); |
| 64 | + var hmac = cipher_blob[2]; |
| 65 | + var decryptor; |
| 66 | + |
| 67 | + chmac = crypto.createHmac(HMAC_ALGORITHM, HMAC_KEY); |
| 68 | + chmac.update(ct); |
| 69 | + chmac.update(IV.toString('hex')); |
| 70 | + |
| 71 | + if (!constant_time_compare(chmac.digest('hex'), hmac)) { |
| 72 | + console.log("Encrypted Blob has been tampered with..."); |
| 73 | + return null; |
| 74 | + } |
| 75 | + |
| 76 | + decryptor = crypto.createDecipheriv(ALGORITHM, KEY, IV); |
| 77 | + var decryptedText = decryptor.update(ct, 'hex', 'utf8'); |
| 78 | + return decryptedText + decryptor.final('utf-8'); |
| 79 | + } |
| 80 | + } |
| 81 | +} |
0 commit comments