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