【问题标题】:CryptoJS Encryption (AES)CryptoJS 加密 (AES)
【发布时间】:2021-10-12 09:07:53
【问题描述】:

我的代码是用 Java 编写的,我想将它用于 react-native,但我无法在 react-native 中正确转换它,我在过去 36 小时内一直卡在它里面。

我可以加密代码,但是 api 是写的,我必须创建一个 android 应用程序的副本。

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

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

我的 react.js 代码是:

var CryptoJS = require("crypto-js");
let workingURL = "BiR6DnP2PDlLRiRxlaqzK%2Fp%2BysGnvL6SF2SCZEN%2FUbIBQwJ%2FeDQT8uLuZffcT%2Bkl"
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());

}

为了测试它,我正在使用 react-js,因为 crypto-js 库。

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;
    }
} 

【问题讨论】:

  • 请发布您最近的 CryptoJS 代码并描述问题。
  • 嗨 @Topaco 我已经添加了 reactjs 的代码 sn-p

标签: reactjs react-native cryptojs


【解决方案1】:

在我看来主要问题是密钥的派生。

Java 代码执行KEY 的UTF8 编码,然后使用前16 个字节作为键。在 CryptoJS 代码中,您还执行 appkey 的 UTF8 编码(使用 CryptoJS.enc.Utf8.parse()),然后应用 整个 数据作为键。

您需要缩短数据,例如secSpec.words.slice(0, 16/4))ivSpec 类似,因为您将密钥用作 IV,顺便说一下,这是不安全的。

通过此更改,加密适用于 CryptoJS 代码,并且密文与预期结果/Java 代码的结果匹配(对于真正的密钥):

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>

关于密钥:比 UTF8 解码更强大的是二进制到文本编码,如 Base64 或十六进制。

【讨论】:

  • 非常感谢..你能从代码中删除密钥吗?
  • @TusharPandey - 完成。