Java使用AES加解密
目录
1.1生成密钥
1.2密钥的存储
1.3获取存储的密钥
1.4加解密
1.5使用存储的密钥进行加解密示例
AES是一种对称的加密算法,可基于相同的密钥进行加密和解密。Java采用AES算法进行加解密的逻辑大致如下:
1、生成/获取密钥
2、加/解密
1.1生成密钥
密钥的生成是通过KeyGenerator来生成的。通过获取一个KeyGenerator实例,然后调用其generateKey()方法即可生成一个SecretKey对象。大致逻辑一般如下:
private SecretKey geneKey() throws Exception { //获取一个密钥生成器实例 KeyGenerator keyGenerator = KeyGenerator.getInstance(ALGORITHM); SecureRandom random = new SecureRandom(); random.setSeed("123456".getBytes());//设置加密用的种子,密钥 keyGenerator.init(random); SecretKey secretKey = keyGenerator.generateKey(); return secretKey; }
上述生成密钥的过程中指定了固定的种子,每次生成出来的密钥都是一样的。还有一种形式,我们可以通过不指定SecureRandom对象的种子,即不调用其setSeed方法,这样每次生成出来的密钥都可能是不一样的。
private SecretKey geneKey() throws Exception { //获取一个密钥生成器实例 KeyGenerator keyGenerator = KeyGenerator.getInstance(ALGORITHM); SecureRandom random = new SecureRandom(); keyGenerator.init(random); SecretKey secretKey = keyGenerator.generateKey(); return secretKey; }
通过KeyGenerator的init(keySize)方法进行初始化,而不是通过传递SecureRandom对象进行初始化也可以达到上面的效果,每次生成的密钥都可能是不一样的。但是对应的keySize的指定一定要正确,AES算法的keySize是128。
private SecretKey geneKey() throws Exception { //获取一个密钥生成器实例 KeyGenerator keyGenerator = KeyGenerator.getInstance(ALGORITHM); keyGenerator.init(128); SecretKey secretKey = keyGenerator.generateKey(); return secretKey; }
但是这种每次生成出来的密钥都是不同的情况下,我们需要把加密用的密钥存储起来,以供解密的时候使用,不然就没法进行解密了。
1.2密钥的存储
密钥SecretKey里面最核心的内容就是其中的密钥对应的字节数组,可以通过SecretKey的getEncoded()方法获取。然后把它存储起来即可。最简单的方式就是直接写入一个文件中。
//把上面的密钥存起来 Path keyPath = Paths.get("D:/aes.key"); Files.write(keyPath, secretKey.getEncoded());
1.3获取存储的密钥
获取存储的密钥的核心是把密钥的字节数组转换为对应的SecretKey。这可以通过SecretKeySpec来获取,其实现了SecretKey接口,然后构造参数里面将接收密钥的字节数组。
private SecretKey readKey(Path keyPath) throws Exception { //读取存起来的密钥 byte[] keyBytes = Files.readAllBytes(keyPath); SecretKeySpec keySpec = new SecretKeySpec(keyBytes, ALGORITHM); return keySpec; }
1.4加解密
Java采用AES算法进行加解密的过程是类似的,具体如下:
1、指定算法,获取一个Cipher实例对象
Cipher cipher = Cipher.getInstance(ALGORITHM);//算法是AES
2、生成/读取用于加解密的密钥
SecretKey secretKey = this.geneKey();
3、用指定的密钥初始化Cipher对象,同时指定加解密模式,是加密模式还是解密模式。
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
4、通过update指定需要加密的内容,不可多次调用。
cipher.update(content.getBytes());
5、通过Cipher的dofinal()进行最终的加解密操作。
byte[] result = cipher.doFinal();//加密后的字节数组
通过以上几步就完成了使用AES算法进行加解密的操作了。其实第4、5步是可以合在一起的,即在进行doFinal的时候传递需要进行加解密的内容。但是如果update指定了加密的内容,而doFinal的时候也指定了加密的内容,那最终加密出来的结果将是两次指定的加密内容的和对应的加密结果。
byte[] result = cipher.doFinal(content.getBytes());
以下是一次加解密操作的完整示例。
public class AESTest { private static final String ALGORITHM = "AES"; /** * 生成密钥 * @return * @throws Exception */ private SecretKey geneKey() throws Exception { //获取一个密钥生成器实例 KeyGenerator keyGenerator = KeyGenerator.getInstance(ALGORITHM); SecureRandom random = new SecureRandom(); random.setSeed("123456".getBytes());//设置加密用的种子,密钥 keyGenerator.init(random); SecretKey secretKey = keyGenerator.generateKey(); //把上面的密钥存起来 Path keyPath = Paths.get("D:/aes.key"); Files.write(keyPath, secretKey.getEncoded()); return secretKey; } /** * 读取存储的密钥 * @param keyPath * @return * @throws Exception */ private SecretKey readKey(Path keyPath) throws Exception { //读取存起来的密钥 byte[] keyBytes = Files.readAllBytes(keyPath); SecretKeySpec keySpec = new SecretKeySpec(keyBytes, ALGORITHM); return keySpec; } /** * 加密测试 */ @Test public void testEncrypt() throws Exception { //1、指定算法、获取Cipher对象 Cipher cipher = Cipher.getInstance(ALGORITHM);//算法是AES //2、生成/读取用于加解密的密钥 SecretKey secretKey = this.geneKey(); //3、用指定的密钥初始化Cipher对象,指定是加密模式,还是解密模式 cipher.init(Cipher.ENCRYPT_MODE, secretKey); String content = "Hello AES";//需要加密的内容 //4、更新需要加密的内容 cipher.update(content.getBytes()); //5、进行最终的加解密操作 byte[] result = cipher.doFinal();//加密后的字节数组 //也可以把4、5步组合到一起,但是如果保留了4步,同时又是如下这样使用的话,加密的内容将是之前update传递的内容和doFinal传递的内容的和。 // byte[] result = cipher.doFinal(content.getBytes()); String base64Result = Base64.getEncoder().encodeToString(result);//对加密后的字节数组进行Base64编码 System.out.println("Result: " + base64Result); } /** * 解密测试 */ @Test public void testDecrpyt() throws Exception { Cipher cipher = Cipher.getInstance(ALGORITHM); SecretKey secretKey = this.geneKey(); cipher.init(Cipher.DECRYPT_MODE, secretKey); String content = "pK9Xw4zqTMXYraDadSGJE3x/ftrDxIg2AM/acq0uixA=";//经过Base64加密的待解密的内容 byte[] encodedBytes = Base64.getDecoder().decode(content.getBytes()); byte[] result = cipher.doFinal(encodedBytes);//对加密后的字节数组进行解密 System.out.println("Result: " + new String(result)); } }
1.5使用存储的密钥进行加解密示例
@Test public void test() throws Exception { Cipher cipher = Cipher.getInstance(ALGORITHM); KeyGenerator keyGenerator = KeyGenerator.getInstance(ALGORITHM); keyGenerator.init(128); SecretKey secretKey = keyGenerator.generateKey(); //把上面的密钥存起来 Path keyPath = Paths.get("D:/aes.key"); Files.write(keyPath, secretKey.getEncoded()); //读取存起来的密钥 SecretKey key = this.readKey(keyPath); cipher.init(Cipher.ENCRYPT_MODE, key); cipher.update("Hello World".getBytes()); //密文 byte[] encryptBytes = cipher.doFinal(); System.out.println(Base64.getEncoder().encodeToString(encryptBytes)); //用取出来的密钥进行解密 cipher.init(Cipher.DECRYPT_MODE, key); //明文 byte[] decryptBytes = cipher.doFinal(encryptBytes); System.out.println(new String(decryptBytes)); }
在上面的示例中,我们先生成了一个密钥,然后把它保存到本地文件中,然后再把它读出来,分别用以加密和解密。而且我们加密和解密都是用的同一个Cipher对象,但是在使用前需要重新通过init方法初始化加解密模式。
(Elim写于2017年4月20日星期四)
相关推荐
java代码-java使用AES加密解密 AES-128-ECB加密 ——学习参考资料:仅用于个人学习使用
本文就简单介绍如何通过JAVA实现AES加密: /** * 测试AES加密和解密 * @param args */ public static void main(String[] args) { /**数据初始化**/ String content = "http://www.mbaike.net"; String...
主要介绍了java使用Hex编码解码实现Aes加密解密功能,结合完整实例形式分析了Aes加密解密功能的定义与使用方法,需要的朋友可以参考下
java 实现aes加解密算法,看看吧,是不是有用!有用就顶吧
c/c++与java互通 AES加密解密; 只使用基本string,数组运算实现加密算法;不依赖其它加密lib
压缩包里有两个工程,一个vc6.0一个myeclipse,本帖是修复贴,原帖地址c/c++ 与java互通 AES加密解密,算法ECB/PKCS5PADDING http://download.csdn.net/download/wangsonghiweed/4328267 -来自CSDN,有童鞋反映有...
JAVA解决AES ECB 模式下加密解密;附加国内三方AES加密网站---http://tool.chacuo.net/cryptaes;如有用解决您工作问题,烦请点个赞
Delphi实现AES加密和解密, 同Java加解密兼容
c/c++与java互通 AES加密解密; 只使用基本char,数组运算实现加密算法;不依赖其它加密lib
Java AES加密解密,可以修改key值和偏移量
java代码-使用java解决AES加密解密的源代码 ——学习参考资料:仅用于个人学习使用!
1.采用秘钥为16位长度的加密字符 2.加密算法为AES/ECB/PKCS5Padding 3.解决加解密乱码问题 4.完整的线上可运行代码及各方法及步骤注释 5.无任何插件,java环境直接运行
AES加解密JAVA实现(源码),实现AES加密,16字节,也就是128位密钥加密。
java实现aes加解密
java语言实现AES加解密
java 基于AES实现对文件的加密 解密 有问题 www.willvc.com.cn 能联系到我
本工程可以直接使用,而且与IOS,Android,JAVA,.NET 已调通。 主要用于客户端进行通信,数据之间地安全性。对数据进行加密和解密 AES加密有多种算法模式,下面提供两套模式的可用源码: 一、CBC(Cipher Block ...
在工作中会经常遇到密码加密,URL传参要进行加密,在此我参照一个例子将用java实现的AES加解密程序用实例写出。JS实现AES-GCM加密,java实现AES-GCM解密
NULL 博文链接:https://kanpiaoxue.iteye.com/blog/2322523
ios与android与java通用的AES加解密,亲测可用。