2

I have java code which produce aes encryption code for me now I am trying to use it on javascript using crypto-js but both codes provides different keys I dont know why and how to get the same key here is my code

public static String encrypt(String text, byte[] iv, byte[] key)throws Exception{ 

    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 
    SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
    System.out.println("KEY SPECCCC: "+keySpec); 
    IvParameterSpec ivSpec = new IvParameterSpec(iv); 
    cipher.init(Cipher.ENCRYPT_MODE,keySpec,ivSpec); 
    byte [] results = cipher.doFinal(text.getBytes("UTF-8")); 
    BASE64Encoder encoder = new BASE64Encoder(); 
    return encoder.encode(results); 
} 

JavaScript code

  require(["crypto-js/core", "crypto-js/aes"], function (CryptoJS, AES) {
        ciphertext = CryptoJS.AES.encrypt(JSON.stringify(jsondata),
                        arr.toString(),arr.toString());
  });

string to utf-8

var utf8 = unescape(encodeURIComponent(key));
var arr = [];
for (var i = 0; i < utf8.length; i++) {
    arr.push(utf8.charCodeAt(i));
}
3
  • If you're using only symmetric encryption you need the exact same key at the server and the client. If you send the encryption key from the server to the client or the other way around you need to encrypt your symmetric encryption key. The easiest way to do this would be to use TLS. If you use TLS, then the data as well as key are encrypted, so you don't need to encrypt it yourself. This doesn't provide any security, just a little bit of obfuscation. You should read: nccgroup.trust/us/about-us/newsroom-and-events/blog/2011/august/… Commented Aug 2, 2017 at 18:23
  • Your code is incomplete. Can you show how you decode your key and IV in Java and JS along with the actual values? Commented Aug 2, 2017 at 18:32
  • 1
    The IV must be unpredictable (read: random). Don't use a static IV or the same value as the key, because that makes the cipher deterministic and therefore not semantically secure. An attacker who observes ciphertexts can determine when the same message prefix was sent before. The IV is not secret, so you can send it along with the ciphertext. Usually, it is simply prepended to the ciphertext and sliced off before decryption. Commented Aug 2, 2017 at 18:34

2 Answers 2

2

First of all even tough your code works fine you wont be able to decrypt it back properly because while you are creating your AES cipher in Java you are using CBC Cipher and You are implementing a Padding algorithm which is PKCS5Padding. So your java code does the followings; When it gets the input it first divide it into the 16 bits blocks then if your input doesnt divide into the 16 overall then the reminders will be padded for filling the block with the same number of reminder.You can see what i mean by the following picture.

enter image description here

So it will do the encryption with the padded ciphers in the java side but in the Javascript Part You neither declare what type of Mode Aes will use nor declaring the what type of Padding it suppose to do. So you should add those values into the your code.You can make search following code parts.

                        mode:CryptoJS.mode.CBC,
                        padding: CryptoJS.pad.Pkcs7

About the different keys it is occuring because you are sending a Byte[] in to the your Encrypt method then use this unknown Byte[] while you are creating your Key.You didnt mention why your encryption method will be used in your program but you should create that "Byte[] key" same way in the both method.For instance you can refer following code as a example of generating that but it is not secure way of generating keys I just added it for showing you what I mean by you should generate both keys in the same way.

    //DONT USE THIS IMPLEMENTATION SINCE IT IS NOT SAFE!
    byte[] key = (username + password).getBytes("UTF-8");
Sign up to request clarification or add additional context in comments.

1 Comment

CryptoJS uses CBC mode and PKCS#7 padding by default. The issue is that the "key" is likely a string which CryptoJS treats as a password and derives a key from that.
0

Java code generates an encrypted string and for JavaScript to also generate same encrypted string, Following code works!

(function (CryptoJS) {
    var C_lib = CryptoJS.lib;
    // Converts ByteArray to stadnard WordArray.
    // Example: CryptoJS.MD5(CryptoJS.lib.ByteArray ([ Bytes ])).toString(CryptoJS.enc.Base64);
    C_lib.ByteArray = function (arr) {
        var word = [];
        for (var i = 0; i < arr.length; i += 4) {
            word.push (arr[i + 0] << 24 | arr[i + 1] << 16 | arr[i + 2] << 8 | arr[i + 3] << 0);
        }
        return C_lib.WordArray.create (word, arr.length);
    };
})(CryptoJS);


var IVstring = CryptoJS.lib.ByteArray(your IV bytearray).toString(CryptoJS.enc.Base64);
var keystring = CryptoJS.lib.ByteArray(your KEY bytearray).toString(CryptoJS.enc.Base64);
var text = 'texttobeencrypted';
var key = CryptoJS.enc.Base64.parse(keystring);
var iv  = CryptoJS.enc.Base64.parse(IVstring);
var encrypted = CryptoJS.AES.encrypt(text, key, {iv: iv});
console.log(encrypted.toString());

Edited: Removed dangerous third party resource reference.

1 Comment

Warning, do not include 3rd party scripts when dealing with sensitive data. The careless link reference above could of single-handedly encouraged the developers at mydashpay to link to the resource, resulting in the recent theft of ~ 500 thousand in dash. twitter.com/Dashpay/status/1149552764923465735

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.