java - 如何在 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)。
我用于解密的工具:
- https://webkit.org/demos/webcrypto/aes-gcm.html
- https://encode-decode.com/aes-256-gcm-encrypt-online/
- https://8gwifi.org/CipherFunctions.jsp
- http://aes.online-domain-tools.com/
我不是加密专家,但我问这个问题是因为我已经用尽了大部分努力,而不是因为缺乏尝试,我只需要以下帮助:
- 这段代码有问题吗?
- 这段代码的结果有问题吗?
- 为什么我无法使用提到的工具解密?
感谢您提供帮助。
解决方案
推荐阅读
- php - Laravel 5.7 的 index.php 中定义的 LARAVEL_START const 的实际用法是什么?
- mysql - AGGREGATE SQL 函数上的 QueryDatabaseTable 错误
- bash - Bash:如何使用 for 循环创建映射?
- ios - 使用 GPUImage2 过滤视频流
- ios - 如何使用 Firebase 确保我的代码在 Swift 中按顺序运行?
- php - 如何为 DB::raw 设置绑定?
- react-native - 本地主机上的重定向 url
- arrays - swift中的异构集合文字
- r - 使用 st_distance 计算两组点之间的所有距离
- reactjs - AutocompleteInput 是否可以重置?