![]() |
直爽的饭盒 · 用Gdk::Pixbuf::create_f ...· 3 月前 · |
![]() |
孤独的火龙果 · Linux网络编程errno的EAGAIN和 ...· 10 月前 · |
![]() |
大方的铁板烧 · Newtonsoft.Json:JObjec ...· 11 月前 · |
![]() |
爱旅游的硬币 · C/C++中产生随机数(rand,srand ...· 1 年前 · |
![]() |
年轻有为的人字拖 · swift 5.0 ...· 1 年前 · |
下面的例子有什么问题?
问题是,解密字符串的第一部分是无意义的。但是,其他的都很好,我得到了...
结果:‘�eB6O�geS��I are you?祝您今天愉快。
@Test
public void testEncrypt() {
try {
String s = "Hello there. How are you? Have a nice day.";
// Generate key
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(128);
SecretKey aesKey = kgen.generateKey();
// Encrypt cipher
Cipher encryptCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
encryptCipher.init(Cipher.ENCRYPT_MODE, aesKey);
// Encrypt
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
CipherOutputStream cipherOutputStream = new CipherOutputStream(outputStream, encryptCipher);
cipherOutputStream.write(s.getBytes());
cipherOutputStream.flush();
cipherOutputStream.close();
byte[] encryptedBytes = outputStream.toByteArray();
// Decrypt cipher
Cipher decryptCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
IvParameterSpec ivParameterSpec = new IvParameterSpec(aesKey.getEncoded());
decryptCipher.init(Cipher.DECRYPT_MODE, aesKey, ivParameterSpec);
// Decrypt
outputStream = new ByteArrayOutputStream();
ByteArrayInputStream inStream = new ByteArrayInputStream(encryptedBytes);
CipherInputStream cipherInputStream = new CipherInputStream(inStream, decryptCipher);
byte[] buf = new byte[1024];
int bytesRead;
while ((bytesRead = cipherInputStream.read(buf)) >= 0) {
outputStream.write(buf, 0, bytesRead);
System.out.println("Result: " + new String(outputStream.toByteArray()));
catch (Exception ex) {
ex.printStackTrace();
}
发布于 2014-03-17 10:17:23
很多人,包括我自己,由于遗漏了一些信息,比如忘记转换成Base64,初始化向量,字符集等,所以我想做一个功能齐全的代码。
希望这篇文章能对大家有所帮助:要编译,您需要额外的Apache Commons Codec jar,可以在这里找到: http://commons.apache.org/proper/commons-codec/download_codec.cgi
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
public class Encryptor {
public static String encrypt(String key, String initVector, String value) {
try {
IvParameterSpec iv = new IvParameterSpec(initVector.getBytes("UTF-8"));
SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
byte[] encrypted = cipher.doFinal(value.getBytes());
System.out.println("encrypted string: "
+ Base64.encodeBase64String(encrypted));
return Base64.encodeBase64String(encrypted);
} catch (Exception ex) {
ex.printStackTrace();
return null;
public static String decrypt(String key, String initVector, String encrypted) {
try {
IvParameterSpec iv = new IvParameterSpec(initVector.getBytes("UTF-8"));
SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
byte[] original = cipher.doFinal(Base64.decodeBase64(encrypted));
return new String(original);
} catch (Exception ex) {
ex.printStackTrace();
return null;
public static void main(String[] args) {
String key = "Bar12345Bar12345"; // 128 bit key
String initVector = "RandomInitVector"; // 16 bytes IV
System.out.println(decrypt(key, initVector,
encrypt(key, initVector, "Hello World")));
}
发布于 2018-10-30 02:23:11
在这个答案中,我选择讨论“简单的Java AES加密/解密示例”这一主题,而不是具体的调试问题,因为我认为这将使大多数读者受益。
这是对我的 blog post about AES encryption in Java 的一个简单总结,所以我建议在实现任何东西之前先通读一遍。然而,我仍然会提供一个简单的例子来使用,并给出一些需要注意的问题。
在本例中,我将选择在 Galois/Counter Mode or GCM 模式下使用 authenticated encryption 。原因是在大多数情况下,您需要 integrity and authenticity in combination with confidentiality (在 blog 中阅读更多)。
AES-GCM加密/解密教程
以下是在 Java Cryptography Architecture (JCA) 中使用 AES-GCM 进行加密/解密所需的步骤。 不要与其他示例 混合在一起,因为细微的差异可能会使您的代码完全不安全。
1.创建密钥
因为它取决于您的用例,所以我将假定最简单的情况:随机密钥。
SecureRandom secureRandom = new SecureRandom();
byte[] key = new byte[16];
secureRandom.nextBytes(key);
SecretKey secretKey = SecretKeySpec(key, "AES");
重要信息:
SecureRandom
2.创建初始化向量
使用 initialization vector (IV) 使得相同的密钥将创建不同的 cipher texts 。
byte[] iv = new byte[12]; //NEVER REUSE THIS IV WITH SAME KEY
secureRandom.nextBytes(iv);
重要信息:
SecureRandom
IV is
3.使用IV和Key加密
final Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
GCMParameterSpec parameterSpec = new GCMParameterSpec(128, iv); //128 bit auth tag length
cipher.init(Cipher.ENCRYPT_MODE, secretKey, parameterSpec);
byte[] cipherText = cipher.doFinal(plainText);
重要信息:
JCA使用16字节/ 128位GCM (用于验证integrity/authenticity)
CipherInputStream
cipher.updateAAD(associatedData);
More here.
中使用 associated data
3.序列化到单个消息
只需添加IV和密文即可。如上所述,静脉注射不需要保密。
ByteBuffer byteBuffer = ByteBuffer.allocate(iv.length + cipherText.length);
byteBuffer.put(iv);
byteBuffer.put(cipherText);
byte[] cipherMessage = byteBuffer.array();
如果需要字符串表示,可以选择使用 Base64 进行编码。使用 Android's 或 Java 8's built-in 实现(不要使用Apache Commons Codec -这是一个糟糕的实现)。编码用于将字节数组“转换”为字符串表示,以使其ASCII安全,例如:
String base64CipherMessage = Base64.getEncoder().encodeToString(cipherMessage);
4.准备解密:反序列化
如果您已经对消息进行了编码,请先将其解码为字节数组:
byte[] cipherMessage = Base64.getDecoder().decode(base64CipherMessage)
重要信息:
5.解密
初始化密码,并设置与加密相同的参数:
final Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
//use first 12 bytes for iv
AlgorithmParameterSpec gcmIv = new GCMParameterSpec(128, cipherMessage, 0, 12);
cipher.init(Cipher.DECRYPT_MODE, secretKey, gcmIv);
//use everything from 12 bytes on as ciphertext
byte[] plainText = cipher.doFinal(cipherMessage, 12, cipherMessage.length - 12);
重要信息:
如果您在encryption.期间添加了
cipher.updateAAD(associatedData);
A working code snippet can be found in this gist.
请注意,最新的Android (SDK )和Java (7+)实现应该具有21+-GCM。较旧的版本可能缺少此功能。我仍然选择这种模式,因为与类似的 Encrypt-then-Mac 模式(例如 AES-CBC )相比,它更容易实现,而且效率更高。 See this article on how to implement AES-CBC with HMAC 。
发布于 2015-04-03 02:21:28
这里是一个没有
Apache Commons Codec
的
Base64
的解决方案
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
public class AdvancedEncryptionStandard
private byte[] key;
private static final String ALGORITHM = "AES";
public AdvancedEncryptionStandard(byte[] key)
this.key = key;
* Encrypts the given plain text
* @param plainText The plain text to encrypt
public byte[] encrypt(byte[] plainText) throws Exception
SecretKeySpec secretKey = new SecretKeySpec(key, ALGORITHM);
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
return cipher.doFinal(plainText);
* Decrypts the given byte array
* @param cipherText The data to decrypt
public byte[] decrypt(byte[] cipherText) throws Exception
SecretKeySpec secretKey = new SecretKeySpec(key, ALGORITHM);
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, secretKey);
return cipher.doFinal(cipherText);
}
使用示例:
byte[] encryptionKey = "MZygpewJsCpRrfOr".getBytes(StandardCharsets.UTF_8);
byte[] plainText = "Hello world!".getBytes(StandardCharsets.UTF_8);
AdvancedEncryptionStandard advancedEncryptionStandard = new AdvancedEncryptionStandard(
encryptionKey);
byte[] cipherText = advancedEncryptionStandard.encrypt(plainText);
byte[] decryptedCipherText = advancedEncryptionStandard.decrypt(cipherText);