title: "Invalid AES Block Size" SJCL Decryption
body: <p>Trying to decrypt AES using <a href="https://github.com/RNCryptor/rncryptor-js" rel="nofollow">RNCryptor-js</a> which uses SJCL. After logging all the steps on each end, (other end is <a href="https://github.com/RNCryptor/RNCryptor-python" rel="nofollow">RNCryptor-python</a>) the keys, salts, HMAC hashes, everything matches up. But when I get to the final step:</p>
  
  <pre><code>var aes = new sjcl.cipher.aes(encryption_key);
  sjcl.beware["CBC mode is dangerous because it doesn't protect message integrity."]()
  var decrypted = aes.decrypt(ciphertext, iv);
  </code></pre>
  
  <p>I get the error:</p>
  
  <pre><code> sjcl.exception.invalid {toString: function, message: "invalid aes block size"}
  </code></pre>
  
  <p>Here is the full code:</p>
  
  <p>PBKDF2:</p>
  
  <pre><code>this.KeyForPassword = function(password, salt) {
  
    var hmacSHA256 = function (password) {
        var hasher = new sjcl.misc.hmac(password, sjcl.hash.sha256);
        this.encrypt = function () {
            return hasher.encrypt.apply(hasher, arguments);
        };
    };
    return sjcl.misc.pbkdf2(password, salt, 10000, 32 * 8, hmacSHA256);
  };
  </code></pre>
  
  <p>Decryption (takes a hex input):</p>
  
  <pre><code>this.decrypt = function(password, message, options) {
  
    message = sjcl.codec.hex.toBits(message);
  
    options = options || {};
  
    var version = sjcl.bitArray.extract(message, 0 * 8, 8);
    var options = sjcl.bitArray.extract(message, 1 * 8, 8);
  
    var encryption_salt = sjcl.bitArray.bitSlice(message, 2 * 8, 10 * 8);
    var encryption_key = _this.KeyForPassword(password, encryption_salt, "decryption");
  
    var hmac_salt = sjcl.bitArray.bitSlice(message, 10 * 8, 18 * 8);
    var hmac_key = _this.KeyForPassword(password, hmac_salt, "decryption");
  
    var iv = sjcl.bitArray.bitSlice(message, 18 * 8, 34 * 8);
  
    var ciphertext_end = sjcl.bitArray.bitLength(message) - (32 * 8);
    var ciphertext = sjcl.bitArray.bitSlice(message, 34 * 8, ciphertext_end);
  
    var hmac = sjcl.bitArray.bitSlice(message, ciphertext_end);
    var expected_hmac = new sjcl.misc.hmac(hmac_key).encrypt(sjcl.bitArray.bitSlice(message, 0, ciphertext_end));
  
    if (! sjcl.bitArray.equal(hmac, expected_hmac)) {
      throw new sjcl.exception.corrupt("HMAC mismatch or bad password.");
    }
  
    var aes = new sjcl.cipher.aes(encryption_key);
    sjcl.beware["CBC mode is dangerous because it doesn't protect message integrity."]()
    var decrypted = aes.decrypt(ciphertext, iv);
  
    return decrypted;
  }
  </code></pre>
  
  <p>The error is thrown on the second to last statement where <code>decrypted</code> is defined.</p>
  
  <p>I looked at the sjcl exception and it looks like it's looking for an input of length 4, which I'm guessing is a WordArray. I'm just lost as to how to get a valid input. Like I said, the ciphertext, iv, hmac tag, salts are all being sliced properly on the javascript end. Might just be an encoding problem.</p>
  
  <p>This error also seems to only be happening on json (format: '{"key":"value"}'), when I tried something like "Hello, world" I got back a 4 word array with no errors.</p>
  
  <p>Any suggestions?</p>