簡體   English   中英

使用CryptoJS的AES加密

[英]AES Encrypt using CryptoJS

我需要使用JavaScript實現AES加密。 使用AES / CBC / NoPadding模式,並創建了一種方法來完成16個長度的塊。 我已經使用Java解決了。 看起來像:

public static String encrypt(byte[] key, byte[] initVector, String value) {
    try {
        IvParameterSpec iv = new IvParameterSpec(initVector);
        SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
        Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
        cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
        byte[] encrypted = cipher.doFinal(completeBlocks(value));
        return Base64.encodeBase64String(encrypted);
    } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | InvalidAlgorithmParameterException | IllegalBlockSizeException | BadPaddingException ex) {
        System.out.println("Error: " + ex);
    }

    return null;
}

/**
 * Completes 16 lenght blocks
 *
 * @param message
 *
 *
 */
static byte[] completeBlocks(String message) {
    try {

        int bytesLenght = message.getBytes("UTF-8").length;
        if (bytesLenght % 16 != 0) {
            byte[] newArray = new byte[bytesLenght + (16 - (bytesLenght % 16))];
            System.arraycopy(message.getBytes(), 0, newArray, 0, bytesLenght);
            return newArray;
        }

        return message.getBytes("UTF-8");

    } catch (UnsupportedEncodingException ex) {
        System.out.println("" + ex);
    }
    return null;
}

public static void main(String[] args) {

    String key = "253D3FB468A0E24677C28A624BE0F939";
    String strToEncrypt = "My Secret text";
    final byte[] initVector = new byte[16];
    String resultado = encrypt(new BigInteger(key, 16).toByteArray(), initVector, strToEncrypt.trim());
    System.out.println("ENCRYPTED:");
    System.out.println(resultado);
}

輸入key = 253D3FB468A0E24677C28A624BE0F939strToEncrypt = "My Secret text"和ceros IV。 它拋出

7StScX3LnPUly / VNzBes0w ==

我知道這是所需的輸出。 這是正確的! 我試圖使用JavaScript復制此代碼。 我使用了CryptoJs庫。 但是我無法產生相同的Java輸出。 我嘗試過:

var text = "My Secret text";
var key = CryptoJS.enc.Base64.parse("253D3FB468A0E24677C28A624BE0F939");
var iv  = CryptoJS.enc.Base64.parse("                ");
var encrypted = CryptoJS.AES.encrypt(text, key, {iv: iv});
console.log(encrypted.toString());

var decrypted = CryptoJS.AES.decrypt(encrypted, key, {iv: iv});
console.log(decrypted.toString(CryptoJS.enc.Utf8));

使用相同的輸入,我得到De+CvPVIyiBX2//EE6gXTg==作為輸出。 我究竟做錯了什么? 如何獲得相同的Java輸出? 非常感謝!!

假設您將修復諸如空IV之類的問題,並且這是概念證明,則您的代碼將失敗,因為:

  1. 您在Java中不使用填充,而在JS中則需要使用填充
  2. 您在Java中手動填充空值,而在JS中也需要這樣做
  3. 您對密鑰進行base64解碼,但對base64則不進行解碼(它是字節的十六進制字符串)
  4. Java IV是一個空數組,但是在JS中,您使用空格(並且錯誤地將其視為base64)。

要在JS中復制輸出:

CryptoJS.pad.NoPadding = {pad: function(){}, unpad: function(){}};

var text = "My Secret text\0\0";
var key  = CryptoJS.enc.Hex.parse("253D3FB468A0E24677C28A624BE0F939");
var iv   = CryptoJS.enc.Hex.parse("00000000000000000000000000000000");

var encrypted = CryptoJS.AES.encrypt(text, key, {iv: iv, padding: CryptoJS.pad.NoPadding});

console.log(encrypted.toString());

對於:

7StScX3LnPUly / VNzBes0w ==

如果您想使用自定義IV進行加密,則可以像...

    let iv = CryptoJS.lib.WordArray.random(IV_LENGTH);
    const key = CryptoJS.enc.Utf8.parse(ENCRYPTION_KEY);

    let encrypted = CryptoJS.AES.encrypt(text, key, { iv })

    const encrypted = encrypted.iv+':'+encrypted.ciphertext

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM