写在前面

转载请标明出处:https://blog.csdn.net/ZhijunHong/article/details/114870177,谢谢~

基于项目安全性需要,有时候我们的项目会使用AES 256加解密算法。以下,是针对实现AES256 Padding7加密算法实现的关键步骤解析以及此过程遇到的一些问题总结。

GitHub链接地址:https://github.com/zhijunhong/common_utils/tree/master/aes256

一些概念

对称加密算法

加密和解密用到的密钥是相同的,这种加密方式加密速度非常快,适合经常发送数据的场合;缺点是密钥的传输比较麻烦。

非对称加密算法

加密和解密用的密钥是不同的,这种加密方式是用数学上的难解问题构造的,通常加密解密的速度比较慢,适合偶尔发送数据的场合;优点是密钥传输方便。常见的非对称加密算法为RSA、ECC和EIGamal等。

实际应用中,一般是通过RSA加密AES的密钥,传输到接收方,接收方解密得到AES密钥,然后发送方和接收方用AES密钥来通信。

关于AES 256

高级加密标准(AES,Advanced Encryption Standard)为最常见的对称加密算法。对称加密算法:简单来说就是加密和解密过程中使用的秘钥(根据一定的规则生成)是相同的。

下面简单介绍下各个部分的作用与意义:

  明文P   需要加密的明文
密钥K 用来加密明文的密码,在对称加密算法中,加密与解密的密钥是相同的。密钥为接收方与发送方协商产生,但不可以直接在网络上传输,否则会导致密钥泄漏,通常是通过非对称加密算法加密密钥,然后再通过网络传输给对方,或者直接面对面商量密钥。密钥是绝对不可以泄漏的,否则会被攻击者还原密文,窃取机密数据
AES加密算法 设AES加密函数为E,则 C = E(K, P),其中P为明文,K为密钥,C为密文。也就是说,把明文P和密钥K作为加密函数的参数输入,则加密函数E会输出密文C
密文C 经加密函数处理后,可以在网络传输中传递的密文数
AES解密算法 设AES解密函数为D,则 P = D(K, C),其中C为密文,K为密钥,P为明文。也就是说,把密文C和密钥K作为解密函数的参数输入,则解密函数会输出明文P

AES 256加解密算法实现

本博客重点讲解AES 256加解密算法实现过程;有关AES算法原理部分,网上有很多相关的博客,这里不再赘述。这里要特别指出的一点是,AES 256中的256指的是秘钥K的长度,常见的密钥长度还有128位、192位。密钥的长度不同,推荐加密轮数也不同,如下表所示:

AES 密钥长度(32位比特字) 分组长度(32位比特字) 加密轮数
AES-128 4 4 10
AES-192 6 4 12
AES-256 8 4 14

生成秘钥

生成秘钥的方式是需要另一端解密人员一起协定的,不同的厂商乃至不同的项目,生成秘钥的方式理论上应该都要是不同的。

这里只是为简单举例:

使用用户名username,密码password随机数random经过MD5加密后再经过HAS-256 hash后生成一组密钥,具体代码如下:

byte[] pkey = generatePkey("zhijunhong", "123456", "1111");
/*** 生成秘钥** @param username* @param password* @param random* @return* @throws NoSuchAlgorithmException*/private byte[] generatePkey(String username, String password, String random) throws NoSuchAlgorithmException {String mD5Str = MD5Utility.getMD5DefaultEncode(username + random + password);                              //MD5加密,加密算法见github代码return Sha256Utils.getSHA256ByteArray(random + mD5Str);                                                                           //经过HAS-256 hash}

使用密钥加密明文

从步骤1获取的密钥pkey,还需要指定向量IV,这里随机指定IV为一组数据串,实际项目中,需要和解密端协定统一的IV向量。

 String base64EncryptStr = AESUtils.aesEncryptStr("我是明文 ", pkey, AESUtils.IV);    //密文
/*** @param content 加密前原内容* @param iv* @return base64EncodeStr   aes加密完成后内容* @throws* @Title: aesEncryptStr* @Description: aes对称加密*/public static String aesEncryptStr(String content, byte[] pkey, String iv) {byte[] aesEncrypt = aesEncrypt(content, pkey, iv);                                            //具体方法解析,见下文System.out.println("加密后的byte数组:" + Arrays.toString(aesEncrypt));String base64EncryptStr = Base64Utils.encode(aesEncrypt);System.out.println("加密后 base64EncodeStr:" + base64EncryptStr);return base64EncryptStr;}

对上述加密方法,进行参数说明:

  • content:待加密的明文
  • pkey:**“生成秘钥”**步骤生成的加密秘钥
  • iv:加密向量IV

其中,具体加密方法aesEncrypt(String content, byte[] pkey, String IV)如下:

/*** @param content 需要加密的原内容* @param pkey    密匙* @param* @return*/public static byte[] aesEncrypt(String content, byte[] pkey, String IV) {try {//SecretKey secretKey = generateKey(pkey);//byte[] enCodeFormat = secretKey.getEncoded();SecretKeySpec skey = new SecretKeySpec(pkey, "AES");Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");// "算法/加密/填充"IvParameterSpec iv = new IvParameterSpec(IV.getBytes());cipher.init(Cipher.ENCRYPT_MODE, skey, iv);//初始化加密器byte[] encrypted = cipher.doFinal(content.getBytes("UTF-8"));return encrypted; // 加密} catch (Exception e) {Log.i(TAG,"aesEncrypt() method error:", e);}return null;}

最后,进行一轮base64转码String base64EncryptStr = Base64Utils.encode(aesEncrypt);操作后,输出密文字符串base64EncryptStr。

使用密钥解密密文

秘钥解密的过程其实就是加密的逆过程,如下:解密方法

  /*** @param base64EncryptStr base64处理过的字符串* @param pkey    密匙* @param* @return String    返回类型* @throws Exception* @throws* @Title: aesDecodeStr* @Description: 解密 失败将返回NULL*/public static String aesDecodeStr3(String base64EncryptStr, byte[] pkey, String IV) throws Exception {byte[] base64DecodeStr = Base64Utils.decode(base64EncryptStr);byte[] aesDecode = aesDecode(base64DecodeStr, pkey, IV);if (aesDecode == null) {return null;}String result;result = new String(aesDecode, "UTF-8");return result;}

对上述解密方法,进行参数说明:

  • base64EncryptStr:base64编码过的加密密文
  • pkey:秘钥(同加密秘钥)
  • IV:向量

具体解密过程:先通过base64还原密文编码,再通过aesDecode(byte[] encryptStr, byte[] pkey, String IV)方法进行解密

其中,具体解密方法aesDecode(byte[] encryptStr, byte[] pkey, String IV),基本和加密过程相差不大,如下:

/*** 解密** @param encryptStr 解密前的byte数组* @param pkey    密匙* @param IV* @return result  解密后的byte数组* @throws Exception*/public static byte[] aesDecode(byte[] encryptStr, byte[] pkey, String IV) throws Exception {//SecretKey secretKey = generateKey(pkey);//byte[] enCodeFormat = secretKey.getEncoded();SecretKeySpec skey = new SecretKeySpec(pkey, "AES");IvParameterSpec iv = new IvParameterSpec(IV.getBytes("UTF-8"));Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");// 创建密码器cipher.init(Cipher.DECRYPT_MODE, skey, iv);// 初始化解密器byte[] result = cipher.doFinal(encryptStr);return result; // 解密}

通过上述一系列操作后,最后将获取的字符数组,通过new String(aesDecode, "UTF-8")操作,就可以将密文重新解密成明文*“我是明文”*。

这里有一点需要特别说明一下: 字符的编码往往会影响加解密的结果。同一个字符被ASCII、Unicode和UTF-8编码时,字符编码的位数都是有区别的。很多同学没有注意这个问题,结果会导致解密失败。所以两端在联调加解密算法的时候,最好能约定字符编码统一。

打印明文和解密出的明文日志,如下:

2021-02-24 18:05:33.651 21560-21560/com.example.aes256 I/MainActivity: encryptStr: y9COgiC06V2E1CIuhJbPfg==
2021-02-24 18:05:33.652 21560-21560/com.example.aes256 I/MainActivity: decodeStr: 我是明文

完整代码:https://github.com/zhijunhong/common_utils/tree/master/aes256

最后,如果此篇博文对你有所帮助,别忘了点个赞哟~

参考

AES加密算法的详细介绍与实现

SSL在线工具-AES在线加解密|AES在线加密 非常好用的在线验证AES加解密结果网站

AES256加解密java语言实现相关推荐

  1. aes 256 cbc java,AES256加解密java语言实现

    AES256加解密java语言实现 写在前面 基于项目安全性需要,有时候我们的项目会使用AES 256加解密算法.以下,是针对实现AES256 Padding7加密算法实现的关键步骤解析以及此过程遇到 ...

  2. 密码加解密java语言实现

    目录 前言 1.密码加密的主要方式 2.代码的实现过程 3.整体代码 前言 随着技术的发展,密码加密技术已经越来越普遍越来越多样化,在我们生活中常见的加密算法包括了DES加密算法,AES加密算法,RS ...

  3. 【AES256】Java实现AES256加解密

    AES256加解密比较常见,这里简单记录以供参考! 一.下载 官方JDK默认支持AES-128,在 1.8.0_151 和 1.8.0_152 版本之前,需要从Oracle官网下载安全JAR包方可支持 ...

  4. AES实现加解密-Java

    一.加解密算法生态圈 目前的数据加密技术根据加密密钥类型可分私钥加密(对称加密)系统和公钥加密(非对称加密)系统.对称加密算法是较传统的加密体制,通信双方在加/解密过程中使用他们共享的单一密钥,鉴于其 ...

  5. stm32F4 AES256加解密

    现在高级点的MCU都会带AES加密引擎,软件算有延迟硬件基本可以数据发出结果就马上返回,软件加密库可参考mbedTLS,现在信息安全也是很重要通讯数据,存储数据都会进行加密存储以防被破解防制,我写程序 ...

  6. c语言实现的异或加解密,C语言实现视频异或加/解密

    C语言实现异或加/解密的原理 异或原理很简单,异或一次为加密,再异或一次就成了解密了.看下代码 /** * 加密/解密文件 * *@param sourcefile 要加密/解密的文件名 *@para ...

  7. des加解密java c#,C#编写DES加密、解密类

    这个C#类封装的DES加密解密,可以使用默认秘钥进行加密.解密,也可以自定义秘钥进行加密.解密,调用简单方便. 示例一: using System; using System.Security.Cry ...

  8. TripleDES加解密Java、C#、php通用代码

    TripleDES说明: TripleDES(3Des)和Des都是对称加密算法,TripleDes是Des加密算法的增强版本,这里主要说的是TripleDes加密算法的应用. 工作中由于涉及到不同系 ...

  9. Oracle aes128和aes256加解密

    –aes128加密 DECLAREl_src_data VARCHAR2(20) := 'Source Data';l_type pls_integer := dbms_crypto.encrypt_ ...

  10. php加解密易语言源码,易语言PHP加密源码

    资源介绍: 例程程序置入汇编代码,调用API函数实现易语言与PHP通讯加密协议. session_start(); ini_set("display_errors", 0); $M ...

最新文章

  1. openCV图像矩阵Mat和二维数组的互相转换
  2. C++/GO/多媒体方向
  3. 《啊哈!算法》笔记_Day01
  4. Matlab某医院用光电比色计,数理统计答案(研究生).ppt
  5. 学长毕业日记 :本科毕业论文写成博士论文的神操作20170322
  6. boost::geometry::densify用法的测试程序
  7. mysql 备份 php_PHP备份/还原MySQL数据库的代码
  8. 设计素材模板|春节要来了,素材准备好了么?
  9. 线程安全单例最佳实践,C#中的Lazy是如何保证线程安全的
  10. 百度前端技术学院-task1.8源代码
  11. Trie树---前缀最相似匹配
  12. TIA 和step 7硬件更新网址汇总
  13. 怎么用计算机里的坦克大战,坦克大战怎么使用重坦_坦克大战重坦篇_7k7k坦克大战...
  14. 笔记本开机密码忘记了怎么解决,消除笔记本密码
  15. 关于近期工作的一些感想
  16. Portapack应用开发教程(十五) APRS接收
  17. el-input实现尾部加字
  18. 使用ThreeJs从零开始构建3D智能仓库——第二章(创建地面与门窗)
  19. 毛笔字体设计 让经典字体焕然新生
  20. 数说亚洲杯小组赛:冷门四宗“最”知多少?

热门文章

  1. 数据结构(C#)_排序算法(冒泡排序)
  2. linux装回windows系统,装linux后怎样装回windows?(Linux系统清除Grub的几种方法)
  3. ABAP MIR7预制凭证BAPI
  4. 应届生实习需要注意哪些方面?
  5. python里end的用法_python不换行之end=与逗号的意思及用途
  6. Oracle验证身份证号码有效性
  7. 【汉字识别】基于matlab GUI汉字精准识别【含Matlab源码 2197期】
  8. php删除文件还能修复吗,删除文件恢复
  9. 高斯列主消元法 求非齐次线性方程组 C语言实现代码
  10. 创建Allegro差分对