NodeJS aes-256-cfb 解密仅适用于前 16 个字节

NodeJS aes-256-cfb decryption only works on first 16 bytes

下面的代码(mocha 测试)产生:

  1) crypto should work:
     AssertionError: "a secret message which has more than sixteen bytes" 
== "a secret message�\u001d\r�\u001dͫ\u0000 ~��x\u000f�\u001bZ\u001bp?\u0014\u0010\u0011b��\u0003kJ\u001dcV8\t"

显然消息的前16个字节解密成功,但后续数据有误

(必须使用 'aes-256-cfb',如果我选择 aes-256-ctr,问题就会消失。)

code/testcase:

var assert = require('assert');
var crypto = require('crypto');

describe('crypto', function() {
  it('should work', function () {
    var message = new Buffer('a secret message which has more than sixteen bytes');
    var key = new Buffer('fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210', 'hex');
    var iv = new Buffer('0123456789abcdef0123456789abcdef', 'hex');      

    var encrypted = encrypt(message, key, iv);
    assert.equal(message.length, encrypted.length);

    assert.equal(message.length, encrypted.length);
    assert.equal('05c2aad7bac42ed084739340d47cec9f03d8e94ac7b1e11a56a6654f76ad2c8076bca162303e39b44d043732e98fdd28c52d', encrypted.toString('hex'));

    var decrypted = decrypt(encrypted, key, iv);

    assert.equal('a secret message which has more than sixteen bytes', decrypted.toString('utf8'));
  });
});

function encrypt(data, key, iv) {
  var cipher = crypto.createCipheriv('aes-256-cfb', key, iv);
  var encrypted = cipher.update(data);
  var encfinal = cipher.final();

  return Buffer.concat([encrypted, encfinal]);
}

var decrypt = encrypt;

问题是 aes-256-cfb 不像 aes-256-ctr 不对称。

解决方法是使用 crypto.createDecipheriv 进行解密。