javascript - CryptoJS AES and Java AES encrypted value mismatch -


i trying encrypt in client , decrypt in sever using aes, using cryptojs encrypt in client side cbc mode , nopadding in server side using cipher class same mode , nopadding

function call() {   var key = cryptojs.enc.hex.parse('roshanmathew1989');   var iv  = cryptojs.enc.hex.parse('roshanmathew1989');   var encrypted = cryptojs.aes.encrypt("roshanmathew1989",key,{ iv: iv},       {padding:cryptojs.pad.nopadding});   alert(encrypted.ciphertext.tostring(cryptojs.enc.base64));   alert(encrypted.iv.tostring()); } 

server side code

public class crypto {     private static byte[] key = null;    public void setkey(string key){this.key=key.getbytes();}    public string encrypt(string strtoencrypt)   {     string encryptedstring =null;     try     {       cipher cipher = cipher.getinstance("aes/cbc/nopadding");       final secretkeyspec secretkey = new secretkeyspec(key,"aes");       system.out.println("sdfsdf = "+key.tostring());       ivparameterspec ips = new ivparameterspec(key);       cipher.init(cipher.encrypt_mode, secretkey,ips);       encryptedstring = base64.encodebase64string(cipher.dofinal(strtoencrypt.getbytes()));     }     catch(exception e)     {       system.out.println(" error : "+e.getmessage());     }     return encryptedstring;    } other method omitted .... 

implementation

crypto cry=new crypto(); cry.setkey("roshanmathew1989"); string s=cry.encrypt("roshanmathew1989"); 

results

browser side value =       o64x/bknbu7r2tuq2lubxeflq7wd2ynfasyyhsvuryw= server side value of s =   rrncvier/75fzdjhr884sw== 

can point out mistake?

there few things wrong code:

  • you using hexadecimal decoding of key in javascript, , string.getbytes() - character encoding without specifying character set - in java
  • your key 16 characters (it should 16, 24 or 32 randomized bytes), not in hexadecimals
  • you encrypting instead of decrypting on "server side", although 1 on purpose

take on how perform encoding , character-encoding, essential crypto , performed incorrectly (it's common issue on stackoverflow regarding encryption)


Comments

  1. Given it a long try and finally got it.

    1). CryptoJS uses hex values while java uses bytes for the same String.

    2.) The two other factors which need to be same (apart from the key) are initVector and padding.

    Considering both above we first have to validate that both Java are CryptoJS and encrypting to the same value given the above parameters are same.

    Here is the code for Java


    import javax.crypto.Cipher;
    import javax.crypto.spec.IvParameterSpec;
    import javax.crypto.spec.SecretKeySpec;

    import java.io.UnsupportedEncodingException;
    import java.math.BigInteger;
    import java.util.Base64;

    public class JavaEncryptor {

    private static final String key = "aesEncryptionKey";
    private static final String initVector = "encryptionIntVec";

    public static String toHex(String arg) throws UnsupportedEncodingException {
    return String.format("%020x", new BigInteger(1, arg.getBytes("UTF-8")));
    }


    /**
    * Use these hex value in CryptoJS
    * @throws Exception
    */
    public static void printHexForJS() throws Exception {
    System.out.println("HexKeyForJS : "+ toHex(key));
    System.out.println("HexInitVectorForJS : "+ toHex(initVector));
    }

    public static String encrypt(String value) {
    try {
    IvParameterSpec iv = new IvParameterSpec(initVector.getBytes("UTF-8"));
    SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");


    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
    cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);

    byte[] encrypted = cipher.doFinal(value.getBytes());
    return Base64.getEncoder().encodeToString(encrypted);

    } catch (Exception ex) {
    ex.printStackTrace();
    }
    return null;
    }

    public static void main(String[] args) throws Exception {
    printHexForJS();
    System.out.println(encrypt("MyPlainTextToBeEncrypted"));
    }

    }

    Output of the above program is

    > HexKeyForJS : 616573456e6372797074696f6e4b6579
    > HexInitVectorForJS : 656e6372797074696f6e496e74566563
    > MURKOx14eSOo2vs8ZQyCpXpsoKg8Uzlvyj3byQreVBk=




    And then for JS encryption use the HexKeyForJS and HexInitVectorForJS as in below code

    var text = "ManishMudgal";
    var key = CryptoJS.enc.Hex.parse(HexKeyForJS);
    var iv = CryptoJS.enc.Hex.parse(HexInitVectorForJS);

    var encrypted = CryptoJS.AES.encrypt(text, key, {iv: iv, padding: CryptoJS.pad.Pkcs7});
    console.log(encrypted.toString());

    > Output of the above JS code should be kBgYcrSxz+kbXRnyKIFmSw==


    Which is the same encrypted key generated through Java code
    MURKOx14eSOo2vs8ZQyCpXpsoKg8Uzlvyj3byQreVBk=


    Now Decryption at Crypto End

    CryptoJS.AES.decrypt('MURKOx14eSOo2vs8ZQyCpXpsoKg8Uzlvyj3byQreVBk=', CryptoJS.enc.Hex.parse(HexKeyForJS), {iv: CryptoJS.enc.Hex.parse(HexInitVectorForJS), padding: CryptoJS.pad.Pkcs7}).toString(CryptoJS.enc.Utf8);

    Cheers :)








    ReplyDelete

Post a Comment

Popular posts from this blog

jquery - How can I dynamically add a browser tab? -

node.js - Getting the socket id,user id pair of a logged in user(s) -

keyboard - C++ GetAsyncKeyState alternative -