2015-09-19 3 views
1

Vous essayez de déchiffrer AES en utilisant RNCryptor-js qui utilise SJCL. Après avoir enregistré toutes les étapes à chaque extrémité, (l'autre extrémité est RNCryptor-python) les clés, les sels, les hachages HMAC, tout correspond. Mais quand je suis à l'étape finale:"Taille de bloc AES non valide" Décryptage 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); 

Je reçois l'erreur:

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

Voici le code complet:

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

déchiffrage (prend une entrée hexadécimale):

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

L'erreur est renvoyée sur l'instruction avant-dernière où decrypted est défini.

J'ai regardé l'exception de sjcl et il semble qu'elle cherche une entrée de longueur 4, que je suppose être un WordArray. Je suis juste perdu sur la façon d'obtenir une entrée valide. Comme je l'ai dit, le texte chiffré, iv, tag hmac, les sels sont tous tranchés correctement sur la fin de javascript. Peut-être juste un problème d'encodage.

Cette erreur semble également se produire uniquement sur json (format: '{"key": "value"}'), quand j'ai essayé quelque chose comme "Bonjour, monde" j'ai récupéré un tableau de 4 mots sans erreur .

Des suggestions?

+0

Lorsque vous utilisez JSON, si vous définissez votre code de sortie ciphertext.length c'est-il dire que la longueur est? – WDS

+0

@WDS, 'ciphertext.length' a renvoyé différentes longueurs pour différents json. Pour un plus court j'ai 16, un plus long: 24, un plus long encore: 36. – PizzaPleb

+0

Si j'utilise Crypto-JS au lieu de faire la dernière étape de décryptage je n'obtiens pas d'erreur mais j'obtiens un WordArray vide. – PizzaPleb

Répondre

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

devrait être

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

je aussi des problèmes avec rembourrage qui se passe dans cbc.js(link to source) et il est avéré que je ne l'avais pas inclus bitArray.js(link) qui comprend la fonction d'une xor importante (ne pas confondre avec l'opérateur simple ^).

Ainsi: comprennent bitArray.js

La sortie doit également être compactés:

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

Pour les personnes lisant ceci: n'oubliez pas que les paramètres doivent être en bits: var kbits = sjcl.codec.arrayBuffer.toBits (new Uint8Array (key) .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