如何使用 AES/GCM 加密在 Java 中加密数据并在 Python 中解密?

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

我想从 Java 中加密一个字符串并在 Python 中解密该加密值。使用 AEC GCM 算法。下面是我的java代码

import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.util.Arrays;
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class AESEncryptionUtil {
    public static void main(String[] args) {
        String encString = "Hello, World!";
        String secKey = "hellow world";
        String encrypted = encrypt(encString, secKey);
        System.out.println("Encrypted (Java): " + encrypted);
        String decrypted = decrypt(encrypted, secKey);
        System.out.println("Decrypted (Java): " + decrypted);
    }

    private static final Logger logger = LoggerFactory.getLogger(AESEncryption.class);
    private static final String ENCRYPT_ALGO = "AES/GCM/NoPadding";
    private static final int TAG_LENGTH_BIT = 128;
    private static final int IV_LENGTH_BYTE = 12;
    private static final int SALT_LENGTH_BYTE = 16;
    private static final Charset UTF_8 = StandardCharsets.UTF_8;

    public static String encrypt(String pText, String secKey) {
        try {
            if (pText == null || pText.equals("null")) {
                return null;
            }
            byte[] salt = getRandomNonce(SALT_LENGTH_BYTE);
            byte[] iv = getRandomNonce(IV_LENGTH_BYTE);
            byte[] keyBytes = secKey.getBytes(StandardCharsets.UTF_16);
            SecretKeySpec skeySpec = new SecretKeySpec(Arrays.copyOf(keyBytes, 16), "AES");
            Cipher cipher = Cipher.getInstance(ENCRYPT_ALGO);
            cipher.init(Cipher.ENCRYPT_MODE, skeySpec, new GCMParameterSpec(TAG_LENGTH_BIT, iv));
            byte[] cipherText = cipher.doFinal(pText.getBytes());
            byte[] cipherTextWithIvSalt =
                    ByteBuffer.allocate(iv.length + salt.length + cipherText.length)
                            .put(iv)
                            .put(salt)
                            .put(cipherText)
                            .array();
            return Base64.getEncoder().encodeToString(cipherTextWithIvSalt);
        } catch (Exception ex) {
            logger.error("Error while encrypting:", ex);
        }
        return null;
    }

    public static String decrypt(String cText, String secKey) {
        try {
            if (cText == null || cText.equals("null")) {
                return null;
            }
            byte[] decode = Base64.getDecoder().decode(cText.getBytes(UTF_8));
            ByteBuffer bb = ByteBuffer.wrap(decode);
            byte[] iv = new byte[IV_LENGTH_BYTE];
            bb.get(iv);
            byte[] salt = new byte[SALT_LENGTH_BYTE];
            bb.get(salt);
            byte[] cipherText = new byte[bb.remaining()];
            bb.get(cipherText);
            byte[] keyBytes = secKey.getBytes(StandardCharsets.UTF_16);
            SecretKeySpec skeySpec = new SecretKeySpec(Arrays.copyOf(keyBytes, 16), "AES");
            Cipher cipher = Cipher.getInstance(ENCRYPT_ALGO);
            cipher.init(Cipher.DECRYPT_MODE, skeySpec, new GCMParameterSpec(TAG_LENGTH_BIT, iv));
            byte[] plainText = cipher.doFinal(cipherText);
            return new String(plainText, UTF_8);
        } catch (Exception ex) {
            logger.error("Error while decrypting:", ex);
        }
        return null;
    }

    public static byte[] getRandomNonce(int numBytes) {
        byte[] nonce = new byte[numBytes];
        new SecureRandom().nextBytes(nonce);
        return nonce;
    }
}

我在用 Python 解码密钥和处理身份验证标签时遇到问题。我该如何解决这些问题? 无法更改我的 Java 代码 我尝试在 python 中解密,这给出了错误 invalidTag

回溯(最近一次调用最后一次): 文件“C:\Users\Chethan\Git\ix-cd

python java encryption aes aes-gcm
© www.soinside.com 2019 - 2024. All rights reserved.