如何使用 javascript crypto.subtle 解密通过 java 代码(AES GCM)创建的编码字符串?

问题描述 投票:0回答:1

我正在尝试使用 crypto.subtle 解密 javascript 中的编码字符串。我已经使用 aes gcm 在 java 中编码了这个字符串。请让我知道相当于下面java代码的javascript代码(使用cryto.subtle)。解密在java中工作,只是为了学习,我使用相同的字符串作为密钥和初始化向量。 Javascript 代码在解密时出错。我没有使用nodejs。

JAVA代码

package com.hm.fcs.controller;

import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;

public class AesGcmExample
{
    static String plainText = "pathname=editOffer&offerId=8ab076727fdbba68017ff98c196b0000&mode=sea";
    public static final int GCM_TAG_LENGTH = 16;

    // Password derived AES 256 bits secret key
    public static SecretKey getAESKeyFromPassword(char[] password, byte[] salt)
            throws NoSuchAlgorithmException, InvalidKeySpecException {

        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
        // iterationCount = 65536
        // keyLength = 256
        KeySpec spec = new PBEKeySpec(password, salt, 65536, 256);
        SecretKey secret = new SecretKeySpec(factory.generateSecret(spec).getEncoded(), "AES");
        return secret;

    }

    public static void main(String[] args) throws Exception
    {
        char[] secretKey = "ZXE-ERW-QDD-EGXL".toCharArray();
        byte[] IV = "ZXE-ERW-QDD-EGXL".getBytes();

//        SecureRandom random = new SecureRandom();
//        random.nextBytes(IV);
        System.out.println("original text : "+plainText);
        SecretKey key = getAESKeyFromPassword(secretKey,IV);
        byte[] cipherText = encrypt(plainText.getBytes(), key, IV);
        System.out.println("Encrypted Text : " + Base64.getEncoder().encodeToString(cipherText));

        String decryptedText = decrypt(cipherText, key, IV);
        System.out.println("DeCrypted Text : " + decryptedText);
    }

    public static byte[] encrypt(byte[] plaintext, SecretKey key, byte[] IV) throws Exception
    {
        // Get Cipher Instance
        Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");

        // Create GCMParameterSpec
        GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(GCM_TAG_LENGTH * 8, IV);

        // Initialize Cipher for ENCRYPT_MODE

        cipher.init(Cipher.ENCRYPT_MODE, key, gcmParameterSpec);

        // Perform Encryption
        byte[] cipherText = cipher.doFinal(plaintext);

        return cipherText;
    }

    public static String decrypt(byte[] cipherText, SecretKey key, byte[] IV) throws Exception
    {
        // Get Cipher Instance
        Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");

        // Create GCMParameterSpec
        GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(GCM_TAG_LENGTH * 8, IV);

        // Initialize Cipher for DECRYPT_MODE
        cipher.init(Cipher.DECRYPT_MODE, key, gcmParameterSpec);

        // Perform Decryption
        byte[] decryptedText = cipher.doFinal(cipherText);

        return new String(decryptedText);
    }
}

我正在尝试的Java脚本代码

const pwUtf8 = new TextEncoder().encode("ZXE-ERW-QDD-EGXL");
        console.log("before pwHash");
        const pwHash = await crypto.subtle.digest('SHA-256', pwUtf8);
        console.log("after pwHash");
        const ivStr = "ZXE-ERW-QDD-EGXL";
        // iv as Uint8Array
        const iv = new Uint8Array(Array.from(ivStr).map(ch => ch.charCodeAt(0)));

        const alg = { name: 'AES-GCM',
            iv: iv };
        // generate key from pw
        console.log("before key");
        const key = await crypto.subtle.importKey('raw', pwHash, alg, false, ['decrypt']);
        console.log("after key");
        const ctStr = "lZSyv0+aBh6x2rSdNwo683Oz0TtJDDzSjsIe7muCm3jHgUoSOacsYP3Qiaocr2oms1uIAA7jOHKFhG1ntcuyqnEe/0Z/6xNj5lyDSvcDpYPNAEeD";
        // ciphertext as Uint8Array


        const ctUint8 = new Uint8Array(Array.from(ctStr).map(ch => ch.charCodeAt(0)));


        try {
            // decrypt ciphertext using key
            console.log("before decrypt");
            const plainBuffer = await crypto.subtle.decrypt(alg, key, ctUint8);
            console.log("after decrypt");
            // return plaintext from ArrayBuffer
            return new TextDecoder().decode(plainBuffer);
        } catch (e) {

            console.log("in catch",e);
        }

请帮我解决这个问题。

尝试使用上述 JavaScript 代码进行解密,但不起作用。使用 crypto.subtle 需要与 javascript 中的 java 等效的代码。我没有使用nodejs。 在控制台中获取此内容 未捕获(承诺)错误:OperationError

javascript java aes-gcm
1个回答
0
投票

我找到了一些类似加密的有用链接 https://medium.com/@bh03051999/aes-gcm-encryption-and-decryption-for-python-java-and-typescript-562dcaa96c22

如果您发现任何其他参考/其他方法..请发帖以获得更好的方法

© www.soinside.com 2019 - 2024. All rights reserved.