Home > database >  CryptoJS Encryption (AES)
CryptoJS Encryption (AES)

Time:10-13

my Code is written in Java, I want to use it into react-native, but I am not able to convert it properly in react native, I am stuck in it from last 36 hours.

I am able to encrypt the code , but the apis are written and I have to create a replica of android app.

input is : api/v1/master/Login/PinAuthentication

expected output is : BiR6DnP2PDlLRiRxlaqzK/p ysGnvL6SF2SCZEN/UbIBQwJ/eDQT8uLuZffcT kl

my react.js code is :

var CryptoJS = require("crypto-js");
let workingURL = "BiR6DnP2PDlLRiRxlaqzK/p+ysGnvL6SF2SCZEN/UbIBQwJ/eDQT8uLuZffcT+kl"
let decryptedText = "BiR6DnP2PDlLRiRxlaqzK/p ysGnvL6SF2SCZEN/UbIBQwJ/eDQT8uLuZffcT kl"
let appstring = "api/v1/master/Login/PinAuthentication"
let appkey = "****************************************"

//JFACzfbeLzsha7vB5vl3QMgnl3iYX06LWb3tjjnNTYQkV8ZMFg xEtxY/uM8vEZk
function encrypt10(){

  let ciphertext = CryptoJS.enc.Utf8.parse(appstring)
  let secSpec = [-53, -96, -53, -96, -53, -92, -52, -95, -54, -92, -54, -91, -54, -88, -54, -89]
  let ivSpec = [-53, -96, -53, -96, -53, -92, -52, -95, -54, -92, -54, -91, -54, -88, -54, -89]
  
  ivSpec = CryptoJS.enc.Utf8.parse(appkey)
  secSpec = CryptoJS.enc.Utf8.parse(appkey)

  console.log("ciphertext : "   ciphertext)
  console.log("secSpec : "   secSpec)
  console.log("ivSpec : "   ivSpec)

  var encrypted = CryptoJS.AES.encrypt(ciphertext, secSpec, {
    iv: ivSpec, //yes I used password as iv too. Dont mind.
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.Pkcs7,
    keySize: 128 / 8,
});

console.log(encrypted.toString());

}

to test it I am using react-js because of crypto-js library.

private static byte[] getKeyBytes() throws UnsupportedEncodingException {
    byte[] keyBytes = new byte[16];
    byte[] parameterKeyBytes = KEY.getBytes("UTF-8");
    System.arraycopy(parameterKeyBytes, 0, keyBytes, 0, Math.min(parameterKeyBytes.length, keyBytes.length));
    return keyBytes;
}

public static byte[] encrypt2(String value){
    try{
        byte[] keyBytes = getKeyBytes();
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        SecretKeySpec myKey = new SecretKeySpec(keyBytes, "AES");
        IvParameterSpec IVKey = new IvParameterSpec(keyBytes);
        cipher.init(Cipher.ENCRYPT_MODE, myKey, IVKey);
        byte[] outputBytes = cipher.doFinal(value.getBytes("UTF-8"));
        return outputBytes;
    }catch(Exception err){
        err.printStackTrace();
        return null;
    }
} 

CodePudding user response:

The main problem seems to me to be the derivation of the key.

The Java code performs a UTF8 encoding of KEY and then uses the first 16 bytes as key. In the CryptoJS code, you also perform a UTF8 encoding of appkey (with CryptoJS.enc.Utf8.parse()), but then apply the entire data as key.

You need to shorten the data, e.g. with secSpec.words.slice(0, 16/4)) and analogously for ivSpec, since you use the key as IV, which is insecure by the way.

With this change, encryption works with the CryptoJS code and the ciphertext matches the expected result / the result of the Java Code (for the true key):

let appstring = "api/v1/master/Login/PinAuthentication";
let appkey = "****************************************";

function encrypt10(){

  let plaintext = CryptoJS.enc.Utf8.parse(appstring);
  let secSpec = CryptoJS.enc.Utf8.parse(appkey);    
  let ivSpec = CryptoJS.enc.Utf8.parse(appkey);

  secSpec = CryptoJS.lib.WordArray.create(secSpec.words.slice(0, 16/4));
  ivSpec = CryptoJS.lib.WordArray.create(ivSpec.words.slice(0, 16/4));

  var encrypted = CryptoJS.AES.encrypt(plaintext, secSpec, {iv: ivSpec});

  document.getElementById("ct").innerHTML = encrypted.toString(); 
}

encrypt10();
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/crypto-js.min.js"></script>
<p style="font-family:'Courier New', monospace;" id="ct"></p>

Regarding the key: More robust than a UTF8 decoding is a binary-to-text encoding like Base64 or hex.

  • Related