2015-09-19 3 views
1

Пытается расшифровать AES, используя RNCryptor-js, который использует SJCL. После регистрации всех шагов на каждом конце (другой конец RNCryptor-python) ключи, соли, хэши HMAC, все соответствует. Но когда я добираюсь до конечной стадии:«Недопустимый размер блока AES» Расшифровка SJCL

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); 

Я получаю ошибку:

sjcl.exception.invalid {toString: function, message: "invalid aes block size"} 

Вот полный код:

PBKDF2:

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); 
}; 

дешифрование (принимает шестнадцатеричный вход):

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; 
} 

Ошибка указана на втором в последнем заявлении, где определено значение decrypted.

Я посмотрел на исключение sjcl, и похоже, что он ищет ввод длины 4, который, как я предполагаю, является WordArray. Я просто потерял, как получить действительный ввод. Как я уже сказал, зашифрованный текст, iv, hmac tag, соли все правильно нарезаны на конец javascript. Возможно, это просто проблема кодирования.

Эта ошибка, похоже, происходит только в json (формат: '{"key": "value"}'), когда я пробовал что-то вроде «Hello, world», я получил 4-х словный массив без ошибок ,

Любые предложения?

+0

При использовании JSON, если вы установите код для вывода ciphertext.length, что это о том, что длина есть? – WDS

+0

@WDS, 'ciphertext.length' возвращает различные длины для разных json. Для более короткого я получил 16, более длинный: 24, еще один: 36. – PizzaPleb

+0

Если я использую Crypto-JS вместо этого, чтобы выполнить последний шаг дешифрования, я не получаю ошибки, но я получаю пустой WordArray. – PizzaPleb

ответ

0
var decrypted = aes.decrypt(ciphertext, iv); 

должен быть

var decrypted = sjcl.mode.cbc.decrypt(aes, ciphertext, iv); 

Я также возникли проблемы с набивка происходит в cbc.js(link to source), и оказалось, что я не включил bitArray.js(link), который включает в себя важную функцию xor (не путать с простой оператор ^).

Итак: включают bitArray.js

Выходные данные также должны быть закодированы:

return sjcl.codec.utf8String.fromBits(decrypted); 
+0

Для людей, читающих это: не забывайте, что параметры должны быть в битах: var kbits = sjcl.codec.arrayBuffer.toBits (новый Uint8Array (ключ) .buffer); var aes = new sjcl.cipher.aes (kbits); var plainBinary = sjcl.mode.cbc.decrypt (aes, sjcl.codec.arrayBuffer.toBits (encryptedBinary.buffer), sjcl.codec.arrayBuffer.toBits (iv.buffer)); – David

Смежные вопросы