java学习-AES加解密之AES-128-CBC算法
AES算法简介
AES是一种对称加密算法,或称分组对称加密算法。 是Advanced Encryption Standard高级加密标准,简称AES
AES的基本要求是,采用对称分组密码体制。分组密码算法通常由密钥扩展算法和加密(解密)算法两部分组成
AES加密数据块分组长度必须为128比特(bit位),密钥长度可以是128比特、192比特、256比特中的任意一个(如果数据块及密钥长度不足时,会补齐)。
128位数据块,16byte字节的数据为一组,192位,24字节数据为一组。256位,32字节数据为一组
AES加密有很多轮的重复和变换。大致步骤如下(大概知道步骤就好吧,不想太深入研究):
1、密钥扩展(KeyExpansion),2、初始轮(Initial Round),3、重复轮(Rounds),
每一轮又包括:SubBytes、ShiftRows、MixColumns、AddRoundKey,4、最终轮(Final Round),最终轮没有MixColumns。
AES加密算法有多种加密模式:
1.电码本模式(Electronic Codebook Book (ECB));2.密码分组链接模式(Cipher Block Chaining (CBC));
3.计算器模式(Counter (CTR));4.密码反馈模式(Cipher FeedBack (CFB));5.输出反馈模式(Output FeedBack (OFB))。
ECB:将明文分成若干段相同的小段,然后对每一小段进行加密。
CBC:这种模式是先将明文切分成若干小段,然后每一小段与初始块或者上一段的密文段进行异或运算后,再与密钥进行加密。
参考链接:AES加密的四种模式详解
AES加密明文数据的5种填充模式
这些都属于字节填充
PKCS7Padding(PKCS#7),PKCS5Padding(PKCS#5),Zero padding,ISO 10126 , ANSI X.923
例如,现在数据128位数据块方式进行加密,即16字节数据,,,现在有字符串String encryptedStr = "012345678912"
note:由于utf-8下汉字字节长度是可变的,所以直接使用英文或数字字符串举例。
上面数据的字符串长度为12字节,还需要补充4字节数据。
ANSIX923是最后一个字节数据为所缺字节的数进行填充,其余填0。上面需要补充4字节数据,所以最后一字节填4,其余3字节都填0
ISO10126则是最后一字节填4,剩余的都填0,
PKCS#7 是在填充字节上都填相同的数据,上面数据缺少4字节,所以所有字节上都填4
如果缺少10字节,则在补充的10字节数据上都填a
ANSI X.923:... | DD DD DD DD DD DD DD DD | DD DD DD DD (00 00 00 04)|【除了最后字节,其他填0】
ISO 10126:.... | DD DD DD DD DD DD DD DD | DD DD DD DD (81 A6 23 04)|【除了最后字节,其他随机】
PKCS7(Rfc3852) | DD DD DD DD DD DD DD DD | DD DD DD DD (04 04 04 04)
模式说明:(不完整)
算法/模式/填充 16字节加密后数据长度 不满16字节加密后长度
AES/CBC/NoPadding 16 不支持
AES/CBC/PKCS5Padding 32 16
AES/CBC/ISO10126Padding 32 16
AES/CFB/NoPadding 16 原始数据长度
AES/CFB/PKCS5Padding 32 16
AES/CFB/ISO10126Padding 32 16
AES/ECB/NoPadding 16 不支持
AES/ECB/PKCS5Padding 32 16
AES/ECB/ISO10126Padding 32 16
AES/OFB/NoPadding 16 原始数据长度
AES/OFB/PKCS5Padding 32 16
AES/OFB/ISO10126Padding 32 16
AES/PCBC/NoPadding 16 不支持
AES/PCBC/PKCS5Padding 32 16
AES/PCBC/ISO10126Padding 32 16
AES-128-CBC加密解密算法
这个是使用AES加密算法的CBC模式,使用128位数据块为一组进行加密解密,
即16字节明文,对应16字节密文,,明文加密时,如果数据不够16字节,则会将数据补全剩余字节
- 若最后剩余的明文不够16字节,需要进行填充,通常采用PKCS7进行填充。比如最后缺3个字节,则填充3个字节的0x03;若最后缺10个字节,则填充10个字节的0x0a;
- 若明文正好是16个字节的整数倍,最后要再加入一个16字节0x10的组再进行加密
加密时需要的参数
1、传入要加密的明文
2、传入一个16字节的key
3、传入一个16字节的初始偏移向量IV 用初始向量和密钥加密第一组数据,然后把第一组数据加密后的密文重新赋值给IV,然后进行第二组加密,循环进行直到结束
解密时需要参数
1、带解密的密文
2、加密解密的key一致
3、跟加密时传递IV参数一致
AES加密解密类
需要额外的jar包bcprov-jdk16-1.46-sources.jar
可添加依赖
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk16</artifactId>
<version>1.46</version>
</dependency>
AES.java
import java.security.AlgorithmParameters;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchProviderException;
import java.security.Security;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import org.bouncycastle.jce.provider.BouncyCastleProvider; public class AES { //加密方式
public static String KEY_ALGORITHM = "AES";
//数据填充方式
String algorithmStr = "AES/CBC/PKCS7Padding";
//避免重复new生成多个BouncyCastleProvider对象,因为GC回收不了,会造成内存溢出
//只在第一次调用decrypt()方法时才new 对象
public static boolean initialized = false; /**
*
* @param originalContent
* @param encryptKey
* @param ivByte
* @return
*/
public byte[] encrypt(byte[] originalContent, byte[] encryptKey, byte[] ivByte) {
initialize();
try {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKeySpec skeySpec = new SecretKeySpec(encryptKey, "AES");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, new IvParameterSpec(ivByte));
byte[] encrypted = cipher.doFinal(originalContent);
return encrypted;
} catch (Exception e) {
throw new RuntimeException(e);
}
} /**
* AES解密
* 填充模式AES/CBC/PKCS7Padding
* 解密模式128
* @param content
* 目标密文
* @return
* @throws Exception
* @throws InvalidKeyException
* @throws NoSuchProviderException
*/
public byte[] decrypt(byte[] content, byte[] aesKey, byte[] ivByte) {
initialize();
try {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
Key sKeySpec = new SecretKeySpec(aesKey, "AES");
cipher.init(Cipher.DECRYPT_MODE, sKeySpec, generateIV(ivByte));// 初始化
byte[] result = cipher.doFinal(content);
return result;
} catch (Exception e) {
throw new RuntimeException(e);
}
} /**BouncyCastle作为安全提供,防止我们加密解密时候因为jdk内置的不支持改模式运行报错。**/
public static void initialize() {
if (initialized)
return;
Security.addProvider(new BouncyCastleProvider());
initialized = true;
} // 生成iv
public static AlgorithmParameters generateIV(byte[] iv) throws Exception {
AlgorithmParameters params = AlgorithmParameters.getInstance("AES");
params.init(new IvParameterSpec(iv));
return params;
}
}
另一种加密算法DES
DES算法的入口参数有三个:Key、Data、Mode。
其中Key为7个字节共56位,是DES算法的工作密钥;
Data为8个字节64位,是要被加密或被解密的数据;
Mode为DES的工作方式,有两种:加密或解密。
java学习-AES加解密之AES-128-CBC算法的更多相关文章
- 数据採集器服务——Socket(今天才发现AES加解密代码跟贴的时候不一样,貌似乱码,不知什么情况)
近期刚做的一个项目.关于 Socket TCP 通信. 需求方提供了一个 ARM 机器,及数据採集器,须要我做一个服务端与数据採集器进行交互. 目的: 数据採集器:定时将读取到的数据发送到服务端. 服 ...
- 学习Java AES加解密字符串和文件方法,然后写个简单工具类
Reference Core Java Volume Ⅱ 10th Edition 1 对称加密 "Java密码扩展"包含了一个Cipher,它是所有密码算法的超类.通过getIn ...
- Java中的AES加解密
直接上代码,Base64使用的是Java8的方法,如没有,替换即可 KEY:即密码 IV:即偏移量,可自订,十六位 加密方式:AES/CBC/PKCS5Padding,128位加密 如果想用256位和 ...
- Java、C#双语版配套AES加解密示例
这年头找个正经能用的东西那是真难,网上一搜索一大堆,正经能用的没几个,得,最后还是得靠自己,正巧遇上需要AES加解密的地方了,而且还是Java和C#间的相互加解密操作,这里做个备忘 这里采用的加解 ...
- C# RSA加解密与验签,AES加解密,以及与JAVA平台的密文加解密
前言: RSA算法是利用公钥与密钥对数据进行加密验证的一种算法.一般是拿私钥对数据进行签名,公钥发给友商,将数据及签名一同发给友商,友商利用公钥对签名进行验证.也可以使用公钥对数据加密,然后用私钥对数 ...
- 转载:Java、C#双语版配套AES加解密示例
转载,原文出处 http://www.cnblogs.com/lzrabbit/p/3639503.html 这年头找个正经能用的东西那是真难,网上一搜索一大堆,正经能用的没几个,得,最后还是得靠自己 ...
- 记一次Java AES 加解密 对应C# AES加解密 的一波三折
最近在跟三方对接 对方采用AES加解密 作为一个资深neter Ctrl CV 是我最大的优点 所以我义正言辞的问他们要了demo java demo代码: public class EncryptD ...
- C#与java中的AES加解密互解算法
一.C#版AES加解密算法 public class AESCode { public string Key { get; set; } public string Encrypt(string va ...
- Java中的AES加解密工具类:AESUtils
本人手写已测试,大家可以参考使用 package com.mirana.frame.utils.encrypt; import com.mirana.frame.constants.SysConsta ...
- AES加解密异常java.security.InvalidKeyException: Illegal key size
AES加解密异常 Java后台AES解密,抛出异常如下:java.security.InvalidKeyException: Illegal key size Illegal key size or ...
随机推荐
- Python 实现WC功能
GitHub仓库:https://github.com/15crmor/PAC 项目要求 基本要求 -c 统计文件字符数 (实现) -w 统计文件词数 (实现) -l 统计文件行数(实现) 扩展功能 ...
- [翻译] FastReport 变量列表使用
使用报表变量时,引用"frxVariables"单元. 变量定义在"TfrxVariable" 类: TfrxVariable = class(TCollect ...
- Linux服务器目录空间不足解决措施
一般情况下工作环境中我们的服务或数据库文件都会存储在一个单独挂载的分区中,一般占空间比较大的大多就是服务的运行日志以及数据库文件,当我们分区的可用空间不足时就需要我们对分区进行扩容,或者找其它方法 ...
- 使用Postman验证TFS Rest API
概述 你可能已经了解到,TFS自2015版本发布以来,开始支持通过REST API的方式提供接口服务,第三方平台可以通过通用的HTTP协议访问TFS系统,获取数据.请求编译等.REST API在原有. ...
- 运行spark官方的graphx 示例 ComprehensiveExample.scala报错解决
运行spark官方的graphx 示例 ComprehensiveExample.scala报错解决 在Idea中,直接运行ComprehensiveExample.scala,报需要指定master ...
- 开源一款强大的文件服务组件(QJ_FileCenter)(系列一)
系列文章 1. 开源一款强大的文件服务组件(QJ_FileCenter)(系列一) 2. 开源一款强大的文件服务组件(QJ_FileCenter)(系列二 安装说明) 3. 开源一款强大的文件服务组件 ...
- Linq to SQL 练习
public class HomeController : Controller { // // GET: /Home/ empentity entity = new empentity(); pub ...
- Android学习之Fragment解析
1.定义 Fragment中文解释是碎片的意思,主要用在大屏幕设备上,例如平板电脑上,支持更加动态和灵活的UI设计.Fragment在你的应用中相当于是一个模块化和可重用的组件,因为Fragm ...
- ovs-vsctl 命令详解
Open vSwitch中有多个命令,分别有不同的作用,大致如下: ovs-vsctl用于控制ovs db ovs-ofctl用于管理OpenFlow switch 的 flow ovs-dpctl用 ...
- python os.path 的使用
import os #该文件所在位置:D:\第1层\第2层\第3层\第4层\第5层\test11.py path1 = os.path.dirname(__file__) print(path1)#获 ...