=Start=
缘由:
整理记录一下用Java进行AES加解密的示例代码,方便以后快速检索和使用。
正文:
参考解答:
常规的AES加解密:
package com.ixyzero.learn.utils; import org.apache.commons.codec.binary.Base64; import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; public class DoCipherTest { 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 (16 chars) String initVector = "RandomInitVector"; // 16 bytes IV (16 chars) System.out.println(decrypt(key, initVector, encrypt(key, initVector, "Hello World"))); } }
在多线程项目中使用ThreadLocal进行优化:
package com.ixyzero.learn.utils; import org.apache.commons.codec.binary.Base64; import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; /** * Created by ixyzero on 2018/8/16. */ public class ThreadLocalCipher { private static String sKey="Bar12345Bar12345"; private static String ivParameter="RandomInitVector"; private static final ThreadLocal<Cipher> encryptCiphers = new ThreadLocal<Cipher>() { @Override protected Cipher initialValue() { try { byte[] raw = sKey.getBytes("ASCII"); SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES"); IvParameterSpec iv = new IvParameterSpec(ivParameter.getBytes()); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv); return cipher; } catch (Exception e) { // ugly but necessary throw new RuntimeException(e); } } }; private static final ThreadLocal<Cipher> decryptCiphers = new ThreadLocal<Cipher>() { @Override protected Cipher initialValue() { try { byte[] raw = sKey.getBytes("ASCII"); SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES"); IvParameterSpec iv = new IvParameterSpec(ivParameter.getBytes()); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv); return cipher; } catch (Exception e) { // ugly but necessary throw new RuntimeException(e); } } }; public static String encrypt(String data) { try { Cipher cipher = encryptCiphers.get(); byte[] encrypted = cipher.doFinal(data.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 encrypted) { try { Cipher cipher = decryptCiphers.get(); 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 sourceData = "Hello World"; String beEncrypted = encrypt(sourceData); String beDecrypted = decrypt(beEncrypted); System.out.println(beEncrypted); System.out.println(beDecrypted); } }
参考链接:
- 用Java进行AES加解密#nice
- Cipher (Java Platform SE 7 )
- JAVA AES加密与解密
- 加密视频文件
- ==
- 创建和保持多个Cipher
- javax.crypto.Cipher 是线程安全的么?
- 高级加密标准AES的工作模式(ECB、CBC、CFB、OFB)
=END=
《 “用Java进行AES加解密” 》 有 8 条评论
Java中的密码填充
https://stackoverflow.com/questions/10935068/what-are-the-cipher-padding-strings-in-java
http://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html#impl
JAVA实现AES加密
https://blog.csdn.net/hbcui1984/article/details/5201247
java对称加密(AES)
http://songjianyong.iteye.com/blog/1571029
http://tool.chacuo.net/cryptaes
最佳安全实践:在 Java 和 Android 中使用AES进行对称加密
https://proandroiddev.com/security-best-practices-symmetric-encryption-with-aes-in-java-7616beaaade9
高级加密标准AES的工作模式(ECB、CBC、CFB、OFB)
https://blog.poxiao.me/p/advanced-encryption-standard-and-block-cipher-mode/
`
1.1. ECB模式(电子密码本模式:Electronic codebook)
1.2. CBC模式(密码分组链接:Cipher-block chaining)
1.3. CFB模式(密文反馈:Cipher feedback)
1.4. OFB模式(输出反馈:Output feedback)
`
AES加密的四种模式详解
https://www.cnblogs.com/liangxuehui/p/4651351.html
什么是 AES-GCM加密算法
https://blog.csdn.net/T0mato_/article/details/53160772
`
GCM (Galois/Counter Mode) 指的是该对称加密采用Counter模式,并带有GMAC消息认证码。
`
What is the difference between CBC and GCM mode?
https://crypto.stackexchange.com/questions/2310/what-is-the-difference-between-cbc-and-gcm-mode
How to choose an AES encryption mode (CBC ECB CTR OCB CFB)?
https://stackoverflow.com/questions/1220751/how-to-choose-an-aes-encryption-mode-cbc-ecb-ctr-ocb-cfb
`
GCM与OCB (在性能和其它属性上)非常相似,但是GCM不受任何专利的限制,是最好的选择。唯一的缺点是实现非常复杂——但是如果使用库,就不必担心这个问题。
`
聊聊AES
https://blog.huoding.com/2019/05/06/739
AES简介
https://github.com/matt-wu/AES
漫画解读:什么是AES算法
https://zhuanlan.zhihu.com/p/45155135
Java中如何对字符串用0进行前导padding
java string format padding with 0
https://stackoverflow.com/questions/473282/how-can-i-pad-an-integer-with-zeros-on-the-left
https://stackoverflow.com/questions/4469717/left-padding-a-string-with-zeros
`
System.out.println(String.format(“%05d”, 111)); // 显示效果为 ‘00111’ 即,长度为5,用0填充不足的部分
System.out.println(String.format(“%05d”, 111111)); // 显示效果为 ‘111111’ 即,超过的不管
`
一场由JDK8小版本引起的血案
https://www.cnblogs.com/steve-jiang/p/11597160.html
Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 8 Download
https://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html
`
# tree $(/usr/libexec/java_home -V)/jre/lib/security
├── blacklist
├── blacklisted.certs
├── cacerts
├── java.policy
├── java.security
├── policy
│ ├── limited
│ │ ├── US_export_policy.jar
│ │ └── local_policy.jar
│ └── unlimited
│ ├── US_export_policy.jar
│ └── local_policy.jar
└── trusted.libraries
`
用Python进行AES加解密
AES Encrypt / Decrypt – Examples #清晰明了,nice
https://cryptobook.nakov.com/symmetric-key-ciphers/aes-encrypt-decrypt-examples
Popular Symmetric Algorithms 流行的对称算法
https://cryptobook.nakov.com/symmetric-key-ciphers/popular-symmetric-algorithms
`
AES (Rijndael)
Salsa20 / ChaCha20
Other Popular Symmetric Ciphers
Insecure Symmetric Algorithms
Symmetric Encryption Schemes / Constructions
Most applications today should prefer some of the above encryption schemes for symmetric encryption, instead of constructing their own encryption scheme. The above schemes are highly-secure, proven, well tested and come out-of-the box from the crypto libraries.
目前,大多数应用程序都会选择上述加密方案中的某些方案进行对称加密,而不是自行构建加密方案。上述方案都是高度安全、经过验证和测试的,并且是加密库开箱即用的方案。
Note that ChaCha20-Poly1305 is high-performance cipher (3 times faster than AES-128-GCM on mobile devices), so it is recommended to be used instead of AES-GCM.
请注意,ChaCha20-Poly1305 是一种高性能密码(在移动设备上比 AES-128-GCM 快 3 倍),因此建议使用它来代替 AES-GCM。
`