...by using sjcl.mode.cbc.encrypt/decrypt rather than sjcl.encrypt/decrypt. The difference is that the sjcl.encrypt/decrypt functions are really convenience methods designed to encrypt and decrypt strings, but don't play nice with binary data, as revealed in the tests in this commit and the previous commit. Basically, if you use them to encrypt and decrypt binary data as a string, it will return the wrong result or an error. The solution is to use the block cipher directly, in this case sjcl.mode.cbc. This also has the advantage of fewer format conversions - no converting to base64 and JSON strings. This makes things faster. Also, it is actually correct unlike the previous method.
38 lines
1.3 KiB
JavaScript
38 lines
1.3 KiB
JavaScript
'use strict';
|
|
var imports = require('soop').imports();
|
|
var sjcl = require('../sjcl');
|
|
var ECIES = require('../common/ECIES');
|
|
|
|
ECIES.symmetricEncrypt = function(key, iv, message) {
|
|
var skey = sjcl.codec.hex.toBits(key.toString('hex'));
|
|
var siv = sjcl.codec.hex.toBits(iv.toString('hex'));
|
|
var smessage = sjcl.codec.hex.toBits(message.toString('hex'));
|
|
|
|
sjcl.beware["CBC mode is dangerous because it doesn't protect message integrity."]();
|
|
|
|
var cipher = new sjcl.cipher.aes(skey);
|
|
var encrypted = sjcl.mode.cbc.encrypt(cipher, smessage, siv);
|
|
var encbuf = new Buffer(sjcl.codec.hex.fromBits(encrypted), 'hex');
|
|
var r = Buffer.concat([iv, encbuf]);
|
|
|
|
return r;
|
|
};
|
|
|
|
ECIES.symmetricDecrypt = function(key, encrypted) {
|
|
var skey = sjcl.codec.hex.toBits(key.toString('hex'));
|
|
var iv = encrypted.slice(0, 16);
|
|
var todecrypt = encrypted.slice(16, encrypted.length);
|
|
|
|
sjcl.beware["CBC mode is dangerous because it doesn't protect message integrity."]();
|
|
|
|
var encbits = sjcl.codec.hex.toBits(todecrypt.toString('hex'));
|
|
var ivbits = sjcl.codec.hex.toBits(iv.toString('hex'));
|
|
var cipher = new sjcl.cipher.aes(skey);
|
|
var decrypted = sjcl.mode.cbc.decrypt(cipher, encbits, ivbits);
|
|
var decbuf = new Buffer(sjcl.codec.hex.fromBits(decrypted), 'hex');
|
|
|
|
return decbuf;
|
|
};
|
|
|
|
module.exports = require('soop')(ECIES);
|