我正在尝试使用 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
我找到了一些类似加密的有用链接 https://medium.com/@bh03051999/aes-gcm-encryption-and-decryption-for-python-java-and-typescript-562dcaa96c22
如果您发现任何其他参考/其他方法..请发帖以获得更好的方法