add encryption mode choice
This commit is contained in:
		
							
								
								
									
										52
									
								
								index.js
									
									
									
									
									
								
							
							
						
						
									
										52
									
								
								index.js
									
									
									
									
									
								
							| @@ -10,7 +10,7 @@ | |||||||
| const crypto = require ('crypto'); | const crypto = require ('crypto'); | ||||||
| const encoding = require ('@scode/encoding-helper'); | const encoding = require ('@scode/encoding-helper'); | ||||||
|  |  | ||||||
| const encryption = { | const encryption_mode_cbc_256 = { | ||||||
|   algorithm:  'aes-256-cbc', |   algorithm:  'aes-256-cbc', | ||||||
|   nonce_size: 16, |   nonce_size: 16, | ||||||
|   key_size:   32, |   key_size:   32, | ||||||
| @@ -19,6 +19,15 @@ const encryption = { | |||||||
|   iterations: 32767 |   iterations: 32767 | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | const encryption_mode_cbc_128 = { | ||||||
|  |   algorithm:  'aes-128-cbc', | ||||||
|  |   nonce_size: 16, | ||||||
|  |   key_size:   16, | ||||||
|  |   hash:       'sha256', | ||||||
|  |   salt_size:  16, | ||||||
|  |   iterations: 40 | ||||||
|  | }; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * creates a random string |  * creates a random string | ||||||
|  * |  * | ||||||
| @@ -149,20 +158,21 @@ function checksum (data) { | |||||||
|  * |  * | ||||||
|  * @param {string} text plaintext |  * @param {string} text plaintext | ||||||
|  * @param {string} pass password |  * @param {string} pass password | ||||||
|  |  * @param {object} mode encryption mode | ||||||
|  * @returns {string} encrypted |  * @returns {string} encrypted | ||||||
|  */ |  */ | ||||||
| function encrypt_aes (text, pass) { | function encrypt_aes (text, pass, mode = encryption_mode_cbc_256) { | ||||||
|   const salt = crypto.randomBytes (encryption.salt_size); |   const salt = crypto.randomBytes (mode.salt_size); | ||||||
|   // eslint-disable-next-line no-sync |   // eslint-disable-next-line no-sync | ||||||
|   const key = crypto.pbkdf2Sync ( |   const key = crypto.pbkdf2Sync ( | ||||||
|     Buffer.from (pass, 'utf-8'), |     Buffer.from (pass, 'utf-8'), | ||||||
|     salt, |     salt, | ||||||
|     encryption.iterations, |     mode.iterations, | ||||||
|     encryption.key_size, |     mode.key_size, | ||||||
|     encryption.hash |     mode.hash | ||||||
|   ); |   ); | ||||||
|   const nonce = crypto.randomBytes (encryption.nonce_size); |   const nonce = crypto.randomBytes (mode.nonce_size); | ||||||
|   const cipher = crypto.createCipheriv (encryption.algorithm, key, nonce); |   const cipher = crypto.createCipheriv (mode.algorithm, key, nonce); | ||||||
|   return Buffer.concat ([ |   return Buffer.concat ([ | ||||||
|     salt, |     salt, | ||||||
|     nonce, |     nonce, | ||||||
| @@ -177,25 +187,31 @@ function encrypt_aes (text, pass) { | |||||||
|  * |  * | ||||||
|  * @param {string} ciphertext encrypted text |  * @param {string} ciphertext encrypted text | ||||||
|  * @param {string} pass password |  * @param {string} pass password | ||||||
|  |  * @param {object} mode encryption mode | ||||||
|  * @param {boolean} rethrow rethrow exceptions instead of returning null |  * @param {boolean} rethrow rethrow exceptions instead of returning null | ||||||
|  * @returns {string} plaintext |  * @returns {string} plaintext | ||||||
|  */ |  */ | ||||||
| function decrypt_aes (ciphertext, pass, rethrow = false) { | function decrypt_aes ( | ||||||
|  |   ciphertext, | ||||||
|  |   pass, | ||||||
|  |   mode = encryption_mode_cbc_256, | ||||||
|  |   rethrow = false | ||||||
|  | ) { | ||||||
|   try { |   try { | ||||||
|     let buf = Buffer.from (ciphertext, 'base64'); |     let buf = Buffer.from (ciphertext, 'base64'); | ||||||
|     const salt = buf.slice (0, encryption.salt_size); |     const salt = buf.slice (0, mode.salt_size); | ||||||
|     buf = buf.slice (encryption.salt_size); |     buf = buf.slice (mode.salt_size); | ||||||
|     // eslint-disable-next-line no-sync |     // eslint-disable-next-line no-sync | ||||||
|     const key = crypto.pbkdf2Sync ( |     const key = crypto.pbkdf2Sync ( | ||||||
|       Buffer.from (pass, 'utf-8'), |       Buffer.from (pass, 'utf-8'), | ||||||
|       salt, |       salt, | ||||||
|       encryption.iterations, |       mode.iterations, | ||||||
|       encryption.key_size, |       mode.key_size, | ||||||
|       encryption.hash |       mode.hash | ||||||
|     ); |     ); | ||||||
|     const nonce = buf.slice (0, encryption.nonce_size); |     const nonce = buf.slice (0, mode.nonce_size); | ||||||
|     buf = buf.slice (encryption.nonce_size); |     buf = buf.slice (mode.nonce_size); | ||||||
|     const cipher = crypto.createDecipheriv (encryption.algorithm, key, nonce); |     const cipher = crypto.createDecipheriv (mode.algorithm, key, nonce); | ||||||
|     return Buffer.concat ([ |     return Buffer.concat ([ | ||||||
|       cipher.update (buf), |       cipher.update (buf), | ||||||
|       cipher.final () |       cipher.final () | ||||||
| @@ -215,6 +231,8 @@ module.exports = { | |||||||
|   decode_signed, |   decode_signed, | ||||||
|   decrypt_aes, |   decrypt_aes, | ||||||
|   encrypt_aes, |   encrypt_aes, | ||||||
|  |   encryption_mode_cbc_128, | ||||||
|  |   encryption_mode_cbc_256, | ||||||
|   get_signature_info, |   get_signature_info, | ||||||
|   hash_sha512, |   hash_sha512, | ||||||
|   random_hex, |   random_hex, | ||||||
|   | |||||||
| @@ -25,7 +25,12 @@ test ('fail decryption', (t) => { | |||||||
| test ('rethrow decryption', (t) => { | test ('rethrow decryption', (t) => { | ||||||
|   const enc = crypto.encrypt_aes ('foo', 'bar'); |   const enc = crypto.encrypt_aes ('foo', 'bar'); | ||||||
|   t.throws (() => { |   t.throws (() => { | ||||||
|     crypto.decrypt_aes (enc, 'baz', true); |     crypto.decrypt_aes ( | ||||||
|  |       enc, | ||||||
|  |       'baz', | ||||||
|  |       crypto.encryption_mode_cbc_256, | ||||||
|  |       true | ||||||
|  |     ); | ||||||
|   }); |   }); | ||||||
| }); | }); | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user