如何使用 Java AES 256 解密解密过去已加密的文本?
How do I decrypt the text which is already encrypted in the past using Java AES 256 Decryption?
我是新手写的JavaAES GCM加解密
我需要使用 Java AES GCM 加密给定的密码并存储在配置文件中。然后,稍后解密它们并获得相同的密码以获得安全许可。
使用 link
中的以下程序
如果我们同时使用同一个SecretKey,那么加密和解密是完美的。
但是,我想第一次加密然后再解密,因为多次加密后应该会产生相同的文本。
能否请您帮助使程序在以后的解密中工作?
package com.javainterviewpoint;
import java.security.SecureRandom;
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class AES_GCM_Example
{
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 static void main(String[] args) throws Exception
{
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);
System.out.println("Original Text : " + plainText);
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 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);
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 SecretKeySpec
SecretKeySpec keySpec = new SecretKeySpec(key.getEncoded(), "AES");
// Create GCMParameterSpec
GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(GCM_TAG_LENGTH * 8, IV);
// Initialize Cipher for DECRYPT_MODE
cipher.init(Cipher.DECRYPT_MODE, keySpec, gcmParameterSpec);
// Perform Decryption
byte[] decryptedText = cipher.doFinal(cipherText);
return new String(decryptedText);
}
}
正如@Erwin Bolwidt 所评论的那样[编辑: 带有评论的答案已被作者删除。]您代码中的问题是您需要使用相同的初始化用于加密的解密向量 (IV)。
您需要将 IV 与密文一起存储,并使用此 IV 进行解密。
传输密文时,例如通过电子邮件,您可以将 IV 和密文 Base64 编码为字符串编码,然后在解密时您 运行 在使用此数据进行解密之前进行 Base64 解码。如果将密文作为字节数组存储在数据库中,则可以将 IV 存储在另一个数据库字段中或将 IV 附加到密文中[并将其剥离以供以后解密]。
我是新手写的JavaAES GCM加解密
我需要使用 Java AES GCM 加密给定的密码并存储在配置文件中。然后,稍后解密它们并获得相同的密码以获得安全许可。
使用 link
中的以下程序如果我们同时使用同一个SecretKey,那么加密和解密是完美的。
但是,我想第一次加密然后再解密,因为多次加密后应该会产生相同的文本。
能否请您帮助使程序在以后的解密中工作?
package com.javainterviewpoint;
import java.security.SecureRandom;
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class AES_GCM_Example
{
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 static void main(String[] args) throws Exception
{
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);
System.out.println("Original Text : " + plainText);
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 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);
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 SecretKeySpec
SecretKeySpec keySpec = new SecretKeySpec(key.getEncoded(), "AES");
// Create GCMParameterSpec
GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(GCM_TAG_LENGTH * 8, IV);
// Initialize Cipher for DECRYPT_MODE
cipher.init(Cipher.DECRYPT_MODE, keySpec, gcmParameterSpec);
// Perform Decryption
byte[] decryptedText = cipher.doFinal(cipherText);
return new String(decryptedText);
}
}
正如@Erwin Bolwidt 所评论的那样[编辑: 带有评论的答案已被作者删除。]您代码中的问题是您需要使用相同的初始化用于加密的解密向量 (IV)。
您需要将 IV 与密文一起存储,并使用此 IV 进行解密。
传输密文时,例如通过电子邮件,您可以将 IV 和密文 Base64 编码为字符串编码,然后在解密时您 运行 在使用此数据进行解密之前进行 Base64 解码。如果将密文作为字节数组存储在数据库中,则可以将 IV 存储在另一个数据库字段中或将 IV 附加到密文中[并将其剥离以供以后解密]。