package com.company.encrypt.tests;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
public class TestEncryptDecrypt {
private static final String characterEncoding = "UTF-8";
private static final String cipherTransformation = "AES/CBC/PKCS5Padding";
private static final String aesEncryptionAlgorithm = "AES";
public static void main(String[] args) throws Exception {
String key1 = "1234567812345678";
String text = "01234567891234565";
System.out.println("Original Text: " + text);
String encrypted = encrypt(text, key1);
System.out.println("Encrypted: " + encrypted);
String decrypted = decrypt(encrypted, key1);
System.out.println("Decrypted: " + decrypted);
}
public static String decrypt(String encryptedText, String key) throws Exception {
String plainText = null;
int keyLength = key.length();
System.out.println("Key length: " + String.valueOf(keyLength));
byte[] encryptedTextBytes = Base64.decodeBase64(encryptedText.getBytes());
byte[] keyBytes = key.getBytes();
byte[] initialVector = Arrays.copyOfRange(encryptedTextBytes, 0, keyLength);
byte[] trimmedCipherText = Arrays.copyOfRange(encryptedTextBytes, keyLength, encryptedTextBytes.length);
try {
Cipher cipher = Cipher.getInstance(cipherTransformation);
SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, aesEncryptionAlgorithm);
IvParameterSpec ivParameterSpec = new IvParameterSpec(initialVector);
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
byte[] clearText;
clearText = cipher.doFinal(trimmedCipherText);
plainText = new String(clearText, characterEncoding);
} catch(NoSuchAlgorithmException | NoSuchPaddingException | IllegalBlockSizeException | BadPaddingException
| InvalidKeyException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return plainText;
}
public static String encrypt(String plainText, String encryptionKey) throws Exception {
SecretKeySpec key = new SecretKeySpec(encryptionKey.getBytes("UTF-8"), aesEncryptionAlgorithm);
Cipher cipher = Cipher.getInstance(cipherTransformation);
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] plainTextBytes = plainText.getBytes("UTF-8");
byte[] encrypted = cipher.doFinal(plainTextBytes);
return new String(Base64.encodeBase64(encrypted));
}
}
我注意到,在decrypt()
函数中,您将加密数组分成两部分:前16个字节,其余部分。您使用前16个字节作为IV进行解密,但是,您没有在encrypt()
中将16个字节IV前置到加密消息的开头。这将导致明文的前16个字节丢失。我想您认为dofinal()
会自动为您做这件事,但事实并非如此。
要解决此问题,在返回加密消息之前,请预置IV,可以使用cipher.getiv()
检索该IV。您可以使用Apache Commons Lang库中的arrayutils.addAll()
来完成这一操作,也可以简单地编写自己的函数来完成这一操作。另一个需要注意的是,IV始终是块大小,对于AES来说是16字节,无论密钥大小如何。
希望这个答案有所帮助!
我使用初始化向量和填充实现了AES 128位加密,如下面的代码所示。我碰巧使用了ColdFusion,但我认为这并不重要。加密结果显示了一些重复模式,这是我没有预料到的,但话说回来,我不知道正确输出的特征。我是否正确地进行了初始化向量和填充? 下面是示例输出: 每个加密字符串都以相同的21个字符结尾: 当原始字符串相同(第3和第4个示例中的“String3”)时,EncryptedString以相
我正在尝试编写方法来加密或解密字符串(大部分是数字)。它适用于某些文本(例如-'1010000011'、'1010000012'、'1010000013'),但也适用于其他文本(例如-'1010000014'、'1010000018'): javax.crypto.BadPadding异常:给定最后一个块没有正确填充 这是我的代码: 要加密的字符串从文件中读取,并在加密后写入其他文件。这些加密的文
尝试将数据解密为用AES-128加密的字节数组,使用字符串密钥"keykeykeykey1" 代码: 给我BadPaddingExc0019。我错过了什么?
所以我有一个AES-256-ecb base64字符串,我用在线工具解码了它。然而,我更喜欢命令行,所以我尝试使用命令行来解码它。 这是我尝试过的,但我得到了严重的解密错误 是加密的base64文本 -aes-256-ecb是加密密码 而366a74cb3c959de17d61db30591c39d1是关键 结果应该是另一个base64字符串:
我得到的输出是: 有人能解释一下是怎么回事吗?我在互联网上看到了很多这样的例子,它们看起来都很好。但在这里,文本没有被解密。 ps:我使用的版本是