首页 > 解决方案 > 如何在 Java 中使用 AES 256 GCM 模式正确加密文本?

问题描述

首先我想提一下,我已经查看了与加密相关的所有其他问题,所以这是一个独特的问题,不以任何形式重复。

我一直在研究这个问题三天,我终于得到了一段加密的代码,但我怀疑这种加密是否正确,因为加密的文本太短,这就是在线解密工具告诉我的任何方法,因为我希望使用独立工具(通过向对方提供密钥)来完成解密,这些是我尝试使用的工具,它们都同意一件事:The provided data/text is too small.

我拥有的代码就像我尝试制作的一样简单:

import javax.crypto.*;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.ByteBuffer;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import java.util.Arrays;
import java.util.Base64;

public class DataEncrypt {

    //static String plainText = "This is a plain text which need to be encrypted by Java AES 256 GCM Encryption Algorithm";
    public static final int AES_KEY_SIZE = 256;
    public static final int GCM_IV_LENGTH = 12;
    public static final int GCM_TAG_LENGTH = 16;


    public  String encrypt(byte[] plaintext)
    {
        String res=null;
        try {


            KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
            keyGenerator.init(AES_KEY_SIZE);

            // Generate Key
            SecretKey key = keyGenerator.generateKey();
            byte[] IV = new byte[GCM_IV_LENGTH];
            SecureRandom random = new SecureRandom();
            random.nextBytes(IV);


            // Get Cipher Instance
            Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");

            // Create SecretKeySpec
            SecretKeySpec keySpec = new SecretKeySpec(key.getEncoded(), "AES");

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

            // Initialize Cipher for ENCRYPT_MODE
            cipher.init(Cipher.ENCRYPT_MODE, keySpec, gcmParameterSpec);

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

             res= "cipheredText= " + cipherText.toString() + "\nkeySpec=" + keySpec.toString() + "\nKey=" +
                     Base64.getEncoder().encodeToString(key.getEncoded());
        }catch (Exception e){

        }
        return res;
    }

}

此行用于调试:

 res= "cipheredText= " + cipherText.toString() + "\nkeySpec=" + keySpec.toString() + "\nKey=" +
                     Base64.getEncoder().encodeToString(key.getEncoded())

这就是我调用函数的方式:

//string number entered here is not actually the same one I used, but it has the same length
    System.out.println(dataEncrypt.encrypt("320900401024111".getBytes()));

这是控制台输出:

cipheredText= [B@2d612431
keySpec=javax.crypto.spec.SecretKeySpec@fffe956d
Key=3OF/L6XHck3imIRO9q8yi/Dr8+h6cMw99/21zMlByuo=

所以我有一个密钥(来自输出),我可以在在线工具中使用它来解密,并且我有一个加密文本(cipheredText)要输入到工具中,但是 cipheredText 似乎很短,或者通常这些工具只是无法归还我的原始字符串 (320900401024111)。

我用于解密的工具:

我不是加密专家,但我问这个问题是因为我已经用尽了大部分努力,而不是因为缺乏尝试,我只需要以下帮助:

  1. 这段代码有问题吗?
  2. 这段代码的结果有问题吗?
  3. 为什么我无法使用提到的工具解密?

感谢您提供帮助。

标签: javasecurityencryptionaes-gcm

解决方案


推荐阅读