AES加解密之ECB、CBC和CFB三种模式
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.RandomStringUtils;import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;/*** AEC加密工具类* @Date: 2019/11/6 14:05*/
@Slf4j
public class AesUtil {/*** 编码格式*/public static final String ENCODING = "utf-8";/*** 密钥算法*/private static final String KEY_ALGORITHM = "AES";public static String encryptCBC(String value, String key) {try {IvParameterSpec iv = new IvParameterSpec(key.getBytes(ENCODING));SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes(ENCODING), KEY_ALGORITHM);Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);byte[] encrypted = cipher.doFinal(value.getBytes());return Base64.encodeBase64String(encrypted);} catch (Exception ex) {log.error("encryptCBC error:", ex);}return null;}public static String decryptCBC(String encrypted, String key) {try {IvParameterSpec iv = new IvParameterSpec(key.getBytes(ENCODING));SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes(ENCODING), KEY_ALGORITHM);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) {log.error("decryptCBC error:", ex);}return null;}/**** AES加密算法,调用Java自有类库,采用CFB模式密文反馈无填充模式,可以保证数据长度在加密前后是相同的* @paramcontent 待加密内容* @paramkey 密钥* @returnbyte[] 加密结果用byte数组表示**/public static String encryptCFB(String content, String key) {try {Cipher aesECB = Cipher.getInstance("AES/CFB/NoPadding");SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(ENCODING), KEY_ALGORITHM);IvParameterSpec ivSpec = new IvParameterSpec(key.getBytes(ENCODING));aesECB.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);byte[] result = aesECB.doFinal(content.getBytes());return Base64.encodeBase64String(result);} catch (Exception ex) {log.error("encryptCFB error:", ex);}return null;}/**** @paramcontent 待解密内容,字符串形式* @paramkey 解密用的密钥* @return 使用字符串形式返回解密内容* @throws Exception**/public static String decryptCFB(String content, String key) {try {Cipher aesECB = Cipher.getInstance("AES/CFB/NoPadding");SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(), KEY_ALGORITHM);IvParameterSpec ivSpec = new IvParameterSpec(key.getBytes());aesECB.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);byte[] result = aesECB.doFinal(Base64.decodeBase64(content));String AES_decode = new String(result, ENCODING);return AES_decode;} catch (Exception ex) {log.error("decryptCFB error:", ex);}return null;}/*** AES加密* @param source 源字符串* @param key 密钥* @return 加密后的密文* @throws Exception*/public static String encryptECB(String source, String key){try {byte[] sourceBytes = source.getBytes(ENCODING);byte[] keyBytes = key.getBytes(ENCODING);Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(keyBytes, KEY_ALGORITHM));byte[] decrypted = cipher.doFinal(sourceBytes);return Base64.encodeBase64String(decrypted);} catch (Exception ex) {log.error("encryptECB error:", ex);}return null;}/*** AES解密* @param encryptStr 加密后的密文* @param key 密钥* @return 源字符串* @throws Exception*/public static String decryptECB(String encryptStr, String key) {try {byte[] sourceBytes = Base64.decodeBase64(encryptStr);byte[] keyBytes = key.getBytes(ENCODING);Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(keyBytes, KEY_ALGORITHM));byte[] decoded = cipher.doFinal(sourceBytes);return new String(decoded, ENCODING);} catch (Exception ex) {log.error("decryptECB error:", ex);}return null;}public static final String randomSecretKey() {return RandomStringUtils.randomNumeric(16);}/*** 十六进制转字符串* @param buf* @return*/public static String parseByte2HexStr(byte buf[]) {StringBuffer sb = new StringBuffer();for (int i = 0; i < buf.length; i++) {String hex = Integer.toHexString(buf[i] & 0xFF);if (hex.length() == 1) {hex = '0' + hex;}sb.append(hex.toUpperCase());}return sb.toString();}/*** 字符串转十六进制* @param hexStr* @return*/public static byte[] parseHexStr2Byte(String hexStr) {if (hexStr.length() < 1) {return null;}byte[] result = new byte[hexStr.length() / 2];for (int i = 0; i < hexStr.length() / 2; i++) {int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);result[i] = (byte) (high * 16 + low);}return result;}public static void main(String[] args) {try {
// String key = RandomStringUtils.randomNumeric(16);String key = "7618927929652544";String content = "{\"username\":\"1\",\"password\":\"1\"}";String encryptStr = AesUtil.encryptCBC(content,key);log.info("key:{}, encryptStr: {}", key, encryptStr);String decryptStr = AesUtil.decryptCBC(encryptStr,key);System.out.println("decryptStr: "+decryptStr);} catch (Exception e) {e.printStackTrace();}}
}
说明:
AES加密后的数据需要转字符串传给服务端,转字符串有两种方式,一种是base64,一种是使用十六进制(Hex),方法中使用的是Base64方式。
Base64方式:编码:Base64.encodeBase64String(result) ;解码:Base64.decodeBase64(content)
Hex方式:转十六进制:parseHexStr2Byte(String hexStr); 转字符串:parseByte2HexStr(byte buf[])
之前在和客户端(使用vue.js) 调试过程中,客户端对加密后的报文转字符串处理方式上有问题。会存在客户端加密,服务端解密失败问题,因此把两种方式都补充了下。
AES加解密之ECB、CBC和CFB三种模式相关推荐
- js实现在线AES加密解密(支持ECB,CBC,并输出Base64或Hex)
具体请参考:AES在线加密/解密
- golang 的AES加解密 (CBC/ECB/CFB 模式)
golang的AES加密和解密的三种模式实现(CBC/ECB/CFB) package mainimport ("bytes""crypto/aes"" ...
- java aes ebc_Delphi XE2+标准AES加解密算法(AES/EBC,CBC/PKCS5Padding-base64)
[实例简介] 实现了AES/ECB/PKCS5Padding.AES/CBC/PKCS5Padding 密钥长度128/192/256bit,密钥0填充.是标准的AES算法,支持在线AES加解密网站互 ...
- aes加密php源码,AES加解密类源码 · ThinkPHP5高阶实战教程 --诠释为API开发而生 · 看云...
# AES加解密类源码 > 根据网络整理 ~~~ /** * Created by PhpStorm. * Power by Mikkle * QQ:776329498 * Date: 2017 ...
- Golang AES 加解密
文章目录 AES 简介 AES 加解密实现 小结 参考文献 AES 简介 利用 Go 提供的 AES 加解密与 Base64 编解码包,我们可以轻松实现 AES 加解密.实现之前,首先了解一下 AES ...
- java aes 工具类_Java中的AES加解密工具类:AESUtils
本人手写已测试,大家可以参考使用 package com.mirana.frame.utils.encrypt; import com.mirana.frame.constants.SysConsta ...
- linux c openssl aes 加解密
1.OpenSSL提供了AES加解密算法的API const char *AES_options(void); AES算法状态,是所有支持或者是部分支持. 返回值:"aes(full)&qu ...
- Openssl Aes加解密使用示例
Openssl Aes加解密使用示例 Aes简介 设置Aes密钥 Aes算法CBC加解密 Aes简介 Aes是分组加密算法,主要基于块加密,选取固定长度的密钥去加密明文中固定长度的块,生成的密文块与明 ...
- 利用openssl进行aes加解密
之前写过aes加密算法简单说明,本篇用openssl对aes的ecb和cbc模式进行代码编写. 现在拿128位的aes加解密进行说明. 首先强调的是,在openssl提供的函数中,加密和解密每次只能针 ...
最新文章
- 《C++ Primer 4th》读书笔记 第5章-表达式
- SDwebimage使用原理(转载)
- 超棒的jQuery矢量地图生成插件 - JQVAMP
- h.264码流解析_一个SPS的nalu及获取视频的分辨率
- 教师招聘要求计算机证,长沙市直教师招聘考试没有计算机证能考么?
- 多行文本溢出显示省略号(…)
- java执行器是什么_Java 并发编程:任务执行器 Executor 接口
- 利用Python进行数据分析(7) pandas基础: Series和DataFrame的简单介绍 一、pandas 是什么 pandas 是基于 NumPy 的一个 Python 数据分析包,主
- JAVA入门级教学之(内存中的空指针异常)
- PHP JSON中文乱码解决方法大全
- 变量、作用域和内存问题
- Using Delegates with Data Readers to Control DAL Responsibility[转]
- H3CV7交换机WEB登录设备方法
- Swift TextView输入字数限制
- 2022.3.19-2022.3.27每周刷题
- 组成新数python_小组组名大全
- 转:经典SQL语句大全(绝对的经典)
- 从知识溢出的视角分析开放式协作
- 使用DriverManager动态加载JDBC驱动时,报:java.sql.SQLException: No suitable driver found for xxxx 错误
- MybatisX 使用 示例