Java使用AES加解密

目录

1.1生成密钥

1.2密钥的存储

1.3获取存储的密钥

1.4加解密

1.5使用存储的密钥进行加解密示例

AES是一种对称的加密算法,可基于相同的密钥进行加密和解密。Java采用AES算法进行加解密的逻辑大致如下:

1、生成/获取密钥

2、加/解密

1.1生成密钥

密钥的生成是通过KeyGenerator来生成的。通过获取一个KeyGenerator实例,然后调用其generateKey()方法即可生成一个SecretKey对象。大致逻辑一般如下:

  1. private SecretKey geneKey() throws Exception {
  2. //获取一个密钥生成器实例
  3. KeyGenerator keyGenerator = KeyGenerator.getInstance(ALGORITHM);
  4. SecureRandom random = new SecureRandom();
  5. random.setSeed("123456".getBytes());//设置加密用的种子,密钥
  6. keyGenerator.init(random);
  7. SecretKey secretKey = keyGenerator.generateKey();
  8. return secretKey;
  9. }

上述生成密钥的过程中指定了固定的种子,每次生成出来的密钥都是一样的。还有一种形式,我们可以通过不指定SecureRandom对象的种子,即不调用其setSeed方法,这样每次生成出来的密钥都可能是不一样的。

  1. private SecretKey geneKey() throws Exception {
  2. //获取一个密钥生成器实例
  3. KeyGenerator keyGenerator = KeyGenerator.getInstance(ALGORITHM);
  4. SecureRandom random = new SecureRandom();
  5. keyGenerator.init(random);
  6. SecretKey secretKey = keyGenerator.generateKey();
  7. return secretKey;
  8. }

通过KeyGenerator的init(keySize)方法进行初始化,而不是通过传递SecureRandom对象进行初始化也可以达到上面的效果,每次生成的密钥都可能是不一样的。但是对应的keySize的指定一定要正确,AES算法的keySize是128。

  1. private SecretKey geneKey() throws Exception {
  2. //获取一个密钥生成器实例
  3. KeyGenerator keyGenerator = KeyGenerator.getInstance(ALGORITHM);
  4. keyGenerator.init(128);
  5. SecretKey secretKey = keyGenerator.generateKey();
  6. return secretKey;
  7. }

但是这种每次生成出来的密钥都是不同的情况下,我们需要把加密用的密钥存储起来,以供解密的时候使用,不然就没法进行解密了。

1.2密钥的存储

密钥SecretKey里面最核心的内容就是其中的密钥对应的字节数组,可以通过SecretKey的getEncoded()方法获取。然后把它存储起来即可。最简单的方式就是直接写入一个文件中。

  1. //把上面的密钥存起来
  2. Path keyPath = Paths.get("D:/aes.key");
  3. Files.write(keyPath, secretKey.getEncoded());

1.3获取存储的密钥

获取存储的密钥的核心是把密钥的字节数组转换为对应的SecretKey。这可以通过SecretKeySpec来获取,其实现了SecretKey接口,然后构造参数里面将接收密钥的字节数组。

  1. private SecretKey readKey(Path keyPath) throws Exception {
  2. //读取存起来的密钥
  3. byte[] keyBytes = Files.readAllBytes(keyPath);
  4. SecretKeySpec keySpec = new SecretKeySpec(keyBytes, ALGORITHM);
  5. return keySpec;
  6. }

1.4加解密

Java采用AES算法进行加解密的过程是类似的,具体如下:

1、指定算法,获取一个Cipher实例对象

  1. Cipher cipher = Cipher.getInstance(ALGORITHM);//算法是AES

2、生成/读取用于加解密的密钥

  1. SecretKey secretKey = this.geneKey();

3、用指定的密钥初始化Cipher对象,同时指定加解密模式,是加密模式还是解密模式。

  1. cipher.init(Cipher.ENCRYPT_MODE, secretKey);

4、通过update指定需要加密的内容,不可多次调用。

  1. cipher.update(content.getBytes());

5、通过Cipher的dofinal()进行最终的加解密操作。

  1. byte[] result = cipher.doFinal();//加密后的字节数组

通过以上几步就完成了使用AES算法进行加解密的操作了。其实第4、5步是可以合在一起的,即在进行doFinal的时候传递需要进行加解密的内容。但是如果update指定了加密的内容,而doFinal的时候也指定了加密的内容,那最终加密出来的结果将是两次指定的加密内容的和对应的加密结果。

  1. byte[] result = cipher.doFinal(content.getBytes());

以下是一次加解密操作的完整示例。

  1. public class AESTest {
  2. private static final String ALGORITHM = "AES";
  3. /**
  4. * 生成密钥
  5. * @return
  6. * @throws Exception
  7. */
  8. private SecretKey geneKey() throws Exception {
  9. //获取一个密钥生成器实例
  10. KeyGenerator keyGenerator = KeyGenerator.getInstance(ALGORITHM);
  11. SecureRandom random = new SecureRandom();
  12. random.setSeed("123456".getBytes());//设置加密用的种子,密钥
  13. keyGenerator.init(random);
  14. SecretKey secretKey = keyGenerator.generateKey();
  15. //把上面的密钥存起来
  16. Path keyPath = Paths.get("D:/aes.key");
  17. Files.write(keyPath, secretKey.getEncoded());
  18. return secretKey;
  19. }
  20. /**
  21. * 读取存储的密钥
  22. * @param keyPath
  23. * @return
  24. * @throws Exception
  25. */
  26. private SecretKey readKey(Path keyPath) throws Exception {
  27. //读取存起来的密钥
  28. byte[] keyBytes = Files.readAllBytes(keyPath);
  29. SecretKeySpec keySpec = new SecretKeySpec(keyBytes, ALGORITHM);
  30. return keySpec;
  31. }
  32. /**
  33. * 加密测试
  34. */
  35. @Test
  36. public void testEncrypt() throws Exception {
  37. //1、指定算法、获取Cipher对象
  38. Cipher cipher = Cipher.getInstance(ALGORITHM);//算法是AES
  39. //2、生成/读取用于加解密的密钥
  40. SecretKey secretKey = this.geneKey();
  41. //3、用指定的密钥初始化Cipher对象,指定是加密模式,还是解密模式
  42. cipher.init(Cipher.ENCRYPT_MODE, secretKey);
  43. String content = "Hello AES";//需要加密的内容
  44. //4、更新需要加密的内容
  45. cipher.update(content.getBytes());
  46. //5、进行最终的加解密操作
  47. byte[] result = cipher.doFinal();//加密后的字节数组
  48. //也可以把4、5步组合到一起,但是如果保留了4步,同时又是如下这样使用的话,加密的内容将是之前update传递的内容和doFinal传递的内容的和。
  49. //      byte[] result = cipher.doFinal(content.getBytes());
  50. String base64Result = Base64.getEncoder().encodeToString(result);//对加密后的字节数组进行Base64编码
  51. System.out.println("Result: " + base64Result);
  52. }
  53. /**
  54. * 解密测试
  55. */
  56. @Test
  57. public void testDecrpyt() throws Exception {
  58. Cipher cipher = Cipher.getInstance(ALGORITHM);
  59. SecretKey secretKey = this.geneKey();
  60. cipher.init(Cipher.DECRYPT_MODE, secretKey);
  61. String content = "pK9Xw4zqTMXYraDadSGJE3x/ftrDxIg2AM/acq0uixA=";//经过Base64加密的待解密的内容
  62. byte[] encodedBytes = Base64.getDecoder().decode(content.getBytes());
  63. byte[] result = cipher.doFinal(encodedBytes);//对加密后的字节数组进行解密
  64. System.out.println("Result: " + new String(result));
  65. }
  66. }

1.5使用存储的密钥进行加解密示例

  1. @Test
  2. public void test() throws Exception {
  3. Cipher cipher = Cipher.getInstance(ALGORITHM);
  4. KeyGenerator keyGenerator = KeyGenerator.getInstance(ALGORITHM);
  5. keyGenerator.init(128);
  6. SecretKey secretKey = keyGenerator.generateKey();
  7. //把上面的密钥存起来
  8. Path keyPath = Paths.get("D:/aes.key");
  9. Files.write(keyPath, secretKey.getEncoded());
  10. //读取存起来的密钥
  11. SecretKey key = this.readKey(keyPath);
  12. cipher.init(Cipher.ENCRYPT_MODE, key);
  13. cipher.update("Hello World".getBytes());
  14. //密文
  15. byte[] encryptBytes = cipher.doFinal();
  16. System.out.println(Base64.getEncoder().encodeToString(encryptBytes));
  17. //用取出来的密钥进行解密
  18. cipher.init(Cipher.DECRYPT_MODE, key);
  19. //明文
  20. byte[] decryptBytes = cipher.doFinal(encryptBytes);
  21. System.out.println(new String(decryptBytes));
  22. }

在上面的示例中,我们先生成了一个密钥,然后把它保存到本地文件中,然后再把它读出来,分别用以加密和解密。而且我们加密和解密都是用的同一个Cipher对象,但是在使用前需要重新通过init方法初始化加解密模式。

(Elim写于2017年4月20日星期四)

Java使用AES加解密相关推荐

  1. Java实现aes加解密

    pom文件的依赖 <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 --> <depe ...

  2. Java 实现 AES 加解密

    毕业课题中需要使用加解密算法,要求加解密前后的数据长度不会变化,查了一些资料,发现可以采用AES加密的CFB跟OFB模式是无填充的模式,可以保持加解密前后数据的长度相等.下面上代码: import j ...

  3. Java笔记-AES加解密(PKCS7padding可用)

    如下代码: package cn.it1995.tool;import org.apache.tomcat.util.codec.binary.Base64; import sun.misc.BASE ...

  4. Web前后端笔记-vue cli及java进行AES加解密

    这里我直接贴代码了. vue cli中,要先导入 npm install crypto-js vue代码如下: import axios from 'axios' import cryptoJS fr ...

  5. Linux下运行java DES AES加解密

    2019独角兽企业重金招聘Python工程师标准>>> DES java源代码如下: import java.security.InvalidKeyException; import ...

  6. 记一次Java AES 加解密 对应C# AES加解密 的一波三折

    最近在跟三方对接 对方采用AES加解密 作为一个资深neter Ctrl CV 是我最大的优点 所以我义正言辞的问他们要了demo java demo代码: public class EncryptD ...

  7. Java code lib aes 加解密

    Java aes 加解密 /*** Created by LvJianwei on 2018/2/8.*/import javax.crypto.Cipher; import javax.crypto ...

  8. ios java aes_PHP7 AES加密解密函数_兼容ios/andriod/java对等加解密

    **PHP7.0 7.1 7.2 7.3 AES对等加解密类 函数文件_兼容ios/andriod/java等** 由于新项目规划要求使用PHP7.2开发环境,但在部分新系统中仍需使用AES加解密方式 ...

  9. java aes 工具类_Java中的AES加解密工具类:AESUtils

    本人手写已测试,大家可以参考使用 package com.mirana.frame.utils.encrypt; import com.mirana.frame.constants.SysConsta ...

最新文章

  1. 3D视觉创新应用(三维重建)竞赛作品系列——人体三维精准量测与动作捕捉
  2. 日常生活小技巧 -- U盘拷贝时提示文件过大问题
  3. [IE9] 开发IE9上的屏幕取词功能
  4. 记一次Git pull之后Permission denied的解决方案
  5. echart 高度 不用 不撑满_装修干货:橱柜高度到底要多高才合适?
  6. 三级python考试难吗_Python自学之路:三级菜单
  7. linux 跳板机得搭建
  8. vue父子组件生命周期执行顺序_Vue.js 父子组件生命周期调用顺序
  9. Linux下安装anaconda,创建虚拟环境python3.7,并且安装深度学习框架pytorch进行模型训练
  10. 图像处理的OTSU算法
  11. ApacheCN 活动汇总 2019.7.19
  12. 单片机设计 电子琴音乐盒(AT89C51)
  13. 135微信编辑html语言,135微信编辑器
  14. TeamCity Angent 配置(Ubuntu)
  15. 2022爱分析・工业互联网实践报告
  16. Vue倒计时动画效果
  17. 博睿数据智能监测终端全面升级,计算能力强大、用户体验真实性高
  18. 研究开发出 3D 打印 “食品墨水”
  19. 华为视频会议TE40
  20. 在下列用户中什么管理计算机的权限最小,计算机网络管理员考试试题和答案

热门文章

  1. 北宋三衙的地位、待遇及其政治作用
  2. Autoware感知瞎学笔记(一)lidar_kf_contour_track
  3. CAD文件怎么转成低版本?教你两个小妙招
  4. 这样做老板,企业才发展!
  5. 廖雪峰Python基础笔记
  6. 海康摄像头二次开发python_海康摄像头的二次开发(java)
  7. Matlab中strcat函数使用
  8. 区间再现公式的理解与应用
  9. TCP/IP, WebSocket 和 MQTT
  10. sublime和vscode 格式化Json ——两步走