blocktrail /
blocktrail-sdk-nodejs
| 1 | var assert = require('assert'); |
||
| 2 | var sjcl = require('sjcl'); |
||
| 3 | var KeyDerivation = require('./keyderivation'); |
||
| 4 | var randomBytes = require('randombytes'); |
||
| 5 | |||
| 6 | var Encryption = { |
||
| 7 | defaultSaltLen: 10, /* can permit changes, no more than 512 bit (128 bytes) */ |
||
| 8 | tagLenBits: 128, /* can permit changes */ |
||
| 9 | ivLenBits: 128, /* fixed */ |
||
| 10 | ivLenWords: 128 / 32 |
||
| 11 | }; |
||
| 12 | |||
| 13 | Encryption.generateSalt = function() { |
||
| 14 | return randomBytes(this.defaultSaltLen); |
||
| 15 | }; |
||
| 16 | |||
| 17 | Encryption.generateIV = function() { |
||
| 18 | return randomBytes(this.ivLenBits / 8); |
||
| 19 | }; |
||
| 20 | |||
| 21 | Encryption.encrypt = function(pt, pw, iterations) { |
||
| 22 | var salt = this.generateSalt(); |
||
| 23 | var iv = this.generateIV(); |
||
| 24 | |||
| 25 | iterations = typeof iterations === 'undefined' ? KeyDerivation.defaultIterations : iterations; |
||
| 26 | return this.encryptWithSaltAndIV(pt, pw, salt, iv, iterations); |
||
| 27 | }; |
||
| 28 | |||
| 29 | Encryption.encryptWithSaltAndIV = function(pt, pw, saltBuf, iv, iterations) { |
||
| 30 | assert(pt instanceof Buffer, 'pt must be provided as a buffer'); |
||
|
0 ignored issues
–
show
|
|||
| 31 | assert(pw instanceof Buffer, 'pw must be provided as a buffer'); |
||
| 32 | assert(iv instanceof Buffer, 'IV must be provided as a buffer'); |
||
| 33 | assert(saltBuf instanceof Buffer, 'saltBuff must be provided as a buffer'); |
||
| 34 | assert(iv.length === 16, 'IV must be exactly 16 bytes'); |
||
| 35 | |||
| 36 | var SL = (new Buffer(1)); |
||
| 37 | var S = saltBuf; |
||
| 38 | var I = new Buffer(4); |
||
| 39 | SL.writeUInt8(saltBuf.length); |
||
| 40 | I.writeUInt32LE(iterations); |
||
| 41 | var header = SL.toString('hex') + S.toString('hex') + I.toString('hex'); |
||
| 42 | |||
| 43 | var key = sjcl.codec.hex.toBits(KeyDerivation.compute(pw, saltBuf, iterations).toString('hex')); |
||
| 44 | var ct_t = sjcl.mode.gcm.encrypt( |
||
| 45 | new sjcl.cipher.aes(key), |
||
| 46 | sjcl.codec.hex.toBits(pt.toString('hex')), |
||
| 47 | sjcl.codec.hex.toBits(iv.toString('hex')), |
||
| 48 | sjcl.codec.hex.toBits(header), |
||
| 49 | this.tagLenBits |
||
| 50 | ); |
||
| 51 | |||
| 52 | // iter || saltLen8 || salt || iv || tag || ct |
||
| 53 | return new Buffer([header, iv.toString('hex'), sjcl.codec.hex.fromBits(ct_t)].join(''), 'hex'); |
||
| 54 | }; |
||
| 55 | |||
| 56 | Encryption.decrypt = function(ct, pw) { |
||
| 57 | assert(ct instanceof Buffer, 'cipherText must be provided as a Buffer'); |
||
|
0 ignored issues
–
show
The variable
Buffer seems to be never declared. If this is a global, consider adding a /** global: Buffer */ comment.
This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed. To learn more about declaring variables in Javascript, see the MDN. Loading history...
|
|||
| 58 | assert(pw instanceof Buffer, 'password must be provided as a Buffer'); |
||
| 59 | var copy = new Buffer(ct, 'hex'); |
||
| 60 | var c = 0; |
||
| 61 | |||
| 62 | var saltLen = copy.readUInt8(c) ; c += 1; |
||
| 63 | var salt = copy.slice(1, c + saltLen); c += saltLen; |
||
| 64 | var iterations = copy.readUInt32LE(c); c += 4; |
||
| 65 | var header = copy.slice(0, c); |
||
| 66 | |||
| 67 | var iv = copy.slice(c, 16 + c); c += 16; |
||
| 68 | var ct_t = copy.slice(c); |
||
| 69 | |||
| 70 | // SaltBuf is required for KeyDerivation. Convert to sjcl where required. |
||
| 71 | var key = KeyDerivation.compute(pw, salt, iterations); |
||
| 72 | var plainText = sjcl.mode.gcm.decrypt( |
||
| 73 | new sjcl.cipher.aes(sjcl.codec.hex.toBits(key.toString('hex'))), |
||
| 74 | sjcl.codec.hex.toBits(ct_t.toString('hex')), |
||
| 75 | sjcl.codec.hex.toBits(iv.toString('hex')), |
||
| 76 | sjcl.codec.hex.toBits(header.toString('hex')), |
||
| 77 | this.tagLenBits |
||
| 78 | ); |
||
| 79 | return new Buffer(sjcl.codec.hex.fromBits(plainText), 'hex'); |
||
| 80 | }; |
||
| 81 | |||
| 82 | module.exports = Encryption; |
||
| 83 |
This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.
To learn more about declaring variables in Javascript, see the MDN.