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.