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 ...
随机推荐
- 计算服务器的pv量算法
如何计算服务器能够承受多大的pv? 你想建设一个能承受500万PV/每天的网站吗? 500万PV是什么概念?服务器每秒要处理多少个请求才能应对?如果计算呢? PV是什么: PV是page view ...
- 关闭父类弹出的ifream窗口
parent.document.getElementById('zhuce').style.display = 'none';
- [label][翻译][JavaScript Regular Expression]JavaScript Regular Expressions
原文:http://www.javascriptkit.com/javatutors/re.shtml 校验用户的输入是每一个软件开发者的必须要做的事情. 正则表达式与模式 如何在JavaScript ...
- jquery ui widgets-datepicker
jquery ui的用法就不在此讲述,直接进入jquery ui的窗体小部件(widgets)——datepicker. 相信很多像我这样子的菜鸟少年,如果同一个页面上有两个input文本输入框是用来 ...
- Java动态绑定与静态绑定
Java动态绑定来自于继承体现,子类继承父类,子类重新覆盖了父类的方法,就是动态绑定,以下举例: (动态绑定是在运行期间) 动物类: /** * 创建一个动物类 * @author Liudeli * ...
- saprk2 structed streaming
netcat (windows) >nc -L -p 9999 import java.sql.Timestamp import org.apache.spark.sql.SparkSessio ...
- SQL Server OS 调度
--SQL SERVER OS 采用合作模式的线程调度模式,即除非Worker主动放弃CPU,否则SQL OS 不会强制剥夺其CPU,从而减少Context Switch --默认设置下,SQL SE ...
- [ASP.NET]uploadify简单使用讲解
背景:在用户控件中使用html 的file控件或者ASP.NET的FileUpLoad控件都无法获取到文件,于是想到听说过的uploadify uploadify官网:www.uploadify.co ...
- C#treeView控件单击事件选中节点滞后问题解决方法
问题描述:在treeView的Click事件中,选中的节点SelectedNode并不是您刚才点击的节点,总是上一次选中的节点,节点选中滞后的问题. 解决方案:在treeView的MouseDown事 ...
- .net core Memcached使用
首先,你要在你电脑上安装配置好Memcached环境哦 Startup类的ConfigureServices中加入 //memcachedcore1 services.AddEnyimMemcache ...