Getting 2 different decrypted values from very similar AES implementation using cryptoJS (getting a wrong result value for the 16th char)

StackOverflow https://stackoverflow.com/questions/18721468

Question

I am trying to implement a encryption helper for a project. These are the cryptoJS versions I am using:

 <script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/aes.js</script>
 <script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/sha1.js">

And this is how I implemented:

var security = function () { };

security.sha1 = function (word) {
    var result = CryptoJS.SHA1(word);
    return result.toString().toUpperCase();
};

security.encrypt = function (content, key, iv) {
    if (key.length != 16) {
        console.error('Use chave de 16 digitos');
        return;
    }
    content = CryptoJS.enc.Utf8.parse(content);
    key = CryptoJS.enc.Utf8.parse(key);
    var iv = CryptoJS.enc.Utf8.parse('1234567812345670');

    var options = {
        mode: CryptoJS.mode.CBC,
        padding: CryptoJS.pad.Pkcs7,
        iv: iv
    };

    var encrypted = CryptoJS.AES.encrypt(content, key, options);

    return encrypted;
};

security.decrypt = function (message, key, iv) {
    if (key.length != 16) {
        console.error('Use chave de 16 digitos');
        return;
    }

    key = CryptoJS.enc.Utf8.parse(key);
    var iv = CryptoJS.enc.Utf8.parse(iv)

    var options = {
        mode: CryptoJS.mode.CBC,
        padding: CryptoJS.pad.Pkcs7,
        iv: iv
    };
    var result = CryptoJS.AES.decrypt(message, key, options);

    return result;
};


$(document).ready(function () {

    var original = "texto#a$ser&criptografado! ! ! !";
    var hash = security.sha1('blablablabla');
    var key = hash.substring(0, 16);
    var iv = '1234567812345678';

    var crypto = security.encrypt(original, key, iv);
    var dcrypt = security.decrypt(crypto, key, iv);

    alert('  original: ' + original+
          '\n\n     sha-1: ' + hash+
          '\n\n       key: ' + key+
          '\n\n resultado: ' + crypto+
          '\n\n     final: ' + dcrypt.toString(CryptoJS.enc.Utf8));

        });

The problem is that I am getting this strange result:

original: texto#a$ser&criptografado! ! ! !

 final: texto#a$ser&crixtografado! ! ! !

It always change the 16th char of the original text. (Here is a jsfiddle for this test)

And here is another test, with the same lib versions, that is working correctly:

var cryptHelper = function(key,iv){if(key!=undefined&&iv!=undefined)this.initForEncryption(key,iv)};

cryptHelper.prototype = {

    key:null,
    iv:null,
    options: null,

    sha1: function(message){
        console.log('message = '+message);
        var result = CryptoJS.SHA1(message);
        return result.toString().toUpperCase();
    },

initForEncryption: function(key,iv){
    if(key!=undefined&&iv!=undefined){
        this.setKey(key);
        this.setIv(iv);
        this.setOptions();
    }else{
        throw new Error('null keyOrIv error');
    }
},

    setKey: function(key){
        if(key!=undefined){
            if (key.length != 16)
                throw new Error('Use chave de 16 digitos');
            else
                this.key=CryptoJS.enc.Utf8.parse(key);
        }
        else if(this.key == undefined)
            throw new Error('nullEncryptionKeyException');
    },

    setIv:function(iv){
        if(iv!=undefined){
            if (iv.length != 16)
                throw new Error('Use iv de 16 digitos');
            else
                this.iv=CryptoJS.enc.Utf8.parse(iv);
        }
        else if(this.iv == undefined)
            throw new Error('nullIvException');
    },

    setOptions: function(){
        this.options = {mode: CryptoJS.mode.CBC,
                        padding: CryptoJS.pad.Pkcs7,
                        iv: this.iv }
    },

    encryptEAS: function(message){
        this.checkValues();
        return CryptoJS.AES.encrypt(CryptoJS.enc.Utf8.parse(message), this.key, this.options);
    },

    decryptEAS: function(message){
        this.checkValues();
        return CryptoJS.AES.decrypt(message, this.key, this.options);
    },

    checkValues: function(){
        if(this.key==undefined || this.iv==undefined)
            throw new Error('method unavailable! please init the crypthelper');
    }
};

var testeCriptografia = function(){
    var helper = new cryptHelper();

    var original = "texto#a$ser&criptografado! ! ! !";
    var hash = helper.sha1('blablablabla');
    var key = hash.substring(0, 16);
    var iv = '1234567812345678';

    helper.initForEncryption(key,iv);

    var crypto = helper.encryptEAS(original);
    var dcrypt = helper.decryptEAS(crypto);

    alert('  original: ' + original+
          '\n\n     sha-1: ' + hash+
          '\n\n       key: ' + key+
          '\n\n resultado: ' + crypto+
          '\n\n     final: ' + dcrypt.toString(CryptoJS.enc.Utf8));
}

$(document).ready(function () {
    testeCriptografia();
});

(Here is the jsfiddle for the 2nd version)

The problem is that I dont know why the 2nd version is working and the first one isnt.

I would appreciate if someone could tell me what I am doing wrong in the first one, or if my implementation is all wrong in both versions.

Thanks.

Was it helpful?

Solution

In your first example, you are using 123456781234567**0** instead of 123456781234567**8** in your encrypt method.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top