◆JAVA加密解密-DES
DES算法提供CBC, OFB, CFB, ECB四种模式,MAC是基于ECB实现的。
一、数据补位
DES数据加解密就是将数据按照8个字节一段进行DES加密或解密得到一段8个字节的密文或者明文,最后一段不足8个字节,按照需求补足8个字节(通常补00或者FF,根据实际要求不同)进行计算,之后按照顺序将计算所得的数据连在一起即可。
这里有个问题就是为什么要进行数据补位?主要原因是DES算法加解密时要求数据必须为8个字节。
二、ECB模式
DES ECB(电子密本方式)其实非常简单,就是将数据按照8个字节一段进行DES加密或解密得到一段8个字节的密文或者明文,最后一段不足8个字节,按照需求补足8个字节进行计算,之后按照顺序将计算所得的数据连在一起即可,各段数据之间互不影响。
三、CBC模式
DES CBC(密文分组链接方式)有点麻烦,它的实现机制使加密的各段数据之间有了联系。其实现的机理如下:
加密步骤如下:
1)首先将数据按照8个字节一组进行分组得到D1D2......Dn(若数据不是8的整数倍,用指定的PADDING数据补位)
2)第一组数据D1与初始化向量I异或后的结果进行DES加密得到第一组密文C1(初始化向量I为全零)
3)第二组数据D2与第一组的加密结果C1异或以后的结果进行DES加密,得到第二组密文C2
4)之后的数据以此类推,得到Cn
5)按顺序连为C1C2C3......Cn即为加密结果。
解密是加密的逆过程,步骤如下:
1)首先将数据按照8个字节一组进行分组得到C1C2C3......Cn
2)将第一组数据进行解密后与初始化向量I进行异或得到第一组明文D1(注意:一定是先解密再异或)
3)将第二组数据C2进行解密后与第一组密文数据进行异或得到第二组数据D2
4)之后依此类推,得到Dn
5)按顺序连为D1D2D3......Dn即为解密结果。
这里注意一点,解密的结果并不一定是我们原来的加密数据,可能还含有你补得位,一定要把补位去掉才是你的原来的数据。
1 **
2 * DES算法
3 */
4 public class DES {
5 /**
6 *
7 * @return DES算法密钥
8 */
9 public static byte[] generateKey() {
10 try {
11
12 // DES算法要求有一个可信任的随机数源
13 SecureRandom sr = new SecureRandom();
14
15 // 生成一个DES算法的KeyGenerator对象
16 KeyGenerator kg = KeyGenerator.getInstance("DES");
17 kg.init(sr);
18
19 // 生成密钥
20 SecretKey secretKey = kg.generateKey();
21
22 // 获取密钥数据
23 byte[] key = secretKey.getEncoded();
24
25 return key;
26 } catch (NoSuchAlgorithmException e) {
27 System.err.println("DES算法,生成密钥出错!");
28 e.printStackTrace();
29 }
30
31 return null;
32 }
33
34 /**
35 * 加密函数
36 *
37 * @param data
38 * 加密数据
39 * @param key
40 * 密钥
41 * @return 返回加密后的数据
42 */
43 public static byte[] encrypt(byte[] data, byte[] key) {
44
45 try {
46
47 // DES算法要求有一个可信任的随机数源
48 SecureRandom sr = new SecureRandom();
49
50 // 从原始密钥数据创建DESKeySpec对象
51 DESKeySpec dks = new DESKeySpec(key);
52
53 // 创建一个密匙工厂,然后用它把DESKeySpec转换成
54 // 一个SecretKey对象
55 SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
56 SecretKey secretKey = keyFactory.generateSecret(dks);
57
58 // using DES in ECB mode
59 Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
60
61 // 用密匙初始化Cipher对象
62 cipher.init(Cipher.ENCRYPT_MODE, secretKey, sr);
63
64 // 执行加密操作
65 byte encryptedData[] = cipher.doFinal(data);
66
67 return encryptedData;
68 } catch (Exception e) {
69 System.err.println("DES算法,加密数据出错!");
70 e.printStackTrace();
71 }
72
73 return null;
74 }
75
76 /**
77 * 解密函数
78 *
79 * @param data
80 * 解密数据
81 * @param key
82 * 密钥
83 * @return 返回解密后的数据
84 */
85 public static byte[] decrypt(byte[] data, byte[] key) {
86 try {
87 // DES算法要求有一个可信任的随机数源
88 SecureRandom sr = new SecureRandom();
89
90 // byte rawKeyData[] = /* 用某种方法获取原始密匙数据 */;
91
92 // 从原始密匙数据创建一个DESKeySpec对象
93 DESKeySpec dks = new DESKeySpec(key);
94
95 // 创建一个密匙工厂,然后用它把DESKeySpec对象转换成
96 // 一个SecretKey对象
97 SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
98 SecretKey secretKey = keyFactory.generateSecret(dks);
99
100 // using DES in ECB mode
101 Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
102
103 // 用密匙初始化Cipher对象
104 cipher.init(Cipher.DECRYPT_MODE, secretKey, sr);
105
106 // 正式执行解密操作
107 byte decryptedData[] = cipher.doFinal(data);
108
109 return decryptedData;
110 } catch (Exception e) {
111 System.err.println("DES算法,解密出错。");
112 e.printStackTrace();
113 }
114
115 return null;
116 }
117
118 /**
119 * 加密函数
120 *
121 * @param data
122 * 加密数据
123 * @param key
124 * 密钥
125 * @return 返回加密后的数据
126 */
127 public static byte[] CBCEncrypt(byte[] data, byte[] key, byte[] iv) {
128
129 try {
130 // 从原始密钥数据创建DESKeySpec对象
131 DESKeySpec dks = new DESKeySpec(key);
132
133 // 创建一个密匙工厂,然后用它把DESKeySpec转换成
134 // 一个SecretKey对象
135 SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
136 SecretKey secretKey = keyFactory.generateSecret(dks);
137
138 // Cipher对象实际完成加密操作
139 Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
140 // 若采用NoPadding模式,data长度必须是8的倍数
141 // Cipher cipher = Cipher.getInstance("DES/CBC/NoPadding");
142
143 // 用密匙初始化Cipher对象
144 IvParameterSpec param = new IvParameterSpec(iv);
145 cipher.init(Cipher.ENCRYPT_MODE, secretKey, param);
146
147 // 执行加密操作
148 byte encryptedData[] = cipher.doFinal(data);
149
150 return encryptedData;
151 } catch (Exception e) {
152 System.err.println("DES算法,加密数据出错!");
153 e.printStackTrace();
154 }
155
156 return null;
157 }
158
159 /**
160 * 解密函数
161 *
162 * @param data
163 * 解密数据
164 * @param key
165 * 密钥
166 * @return 返回解密后的数据
167 */
168 public static byte[] CBCDecrypt(byte[] data, byte[] key, byte[] iv) {
169 try {
170 // 从原始密匙数据创建一个DESKeySpec对象
171 DESKeySpec dks = new DESKeySpec(key);
172
173 // 创建一个密匙工厂,然后用它把DESKeySpec对象转换成
174 // 一个SecretKey对象
175 SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
176 SecretKey secretKey = keyFactory.generateSecret(dks);
177
178 // using DES in CBC mode
179 Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
180 // 若采用NoPadding模式,data长度必须是8的倍数
181 // Cipher cipher = Cipher.getInstance("DES/CBC/NoPadding");
182
183 // 用密匙初始化Cipher对象
184 IvParameterSpec param = new IvParameterSpec(iv);
185 cipher.init(Cipher.DECRYPT_MODE, secretKey, param);
186
187 // 正式执行解密操作
188 byte decryptedData[] = cipher.doFinal(data);
189
190 return decryptedData;
191 } catch (Exception e) {
192 System.err.println("DES算法,解密出错。");
193 e.printStackTrace();
194 }
195
196 return null;
197 }
198
199 public static void main(String[] args) {
200 try {
201 byte[] key = "11111111".getBytes();
202 byte[] iv = "22222222".getBytes();
203 byte[] data = DES.encrypt("ebc mode test".getBytes(), key);
204 System.out.print("EBC mode:");
205 System.out.println(new String(DES.decrypt(data, key)));
206 System.out.print("CBC mode:");
207 data = DES.CBCEncrypt("cbc mode test".getBytes(), key, iv);
208 System.out.println(new String(DES.CBCDecrypt(data, key, iv)));
209
210 } catch (Exception e) {
211 e.printStackTrace();
212 }
213 }
214 }
DES的几种填补方式
DES是对64位数据的加密算法,如数据位数不足64位的倍数,需要填充,补充到64位的倍数。
NoPadding
API或算法本身不对数据进行处理,加密数据由加密双方约定填补算法。例如若对字符串数据进行加解密,可以补充\0或者空格,然后trim
PKCS5Padding
加密前:数据字节长度对8取余,余数为m,若m>0,则补足8-m个字节,字节数值为8-m,即差几个字节就补几个字节,字节数值即为补充的字节数,若为0则补充8个字节的8
解密后:取最后一个字节,值为m,则从数据尾部删除m个字节,剩余数据即为加密前的原文
因为DES是一种block cipher,一个block要8个字节,所以要加密的东西要分成8字节的整数倍,不足的就填充。
PKCS5Padding这种填充,填的字节代表所填字节的总数:
◆JAVA加密解密-DES的更多相关文章
- JAVA加密解密DES对称加密算法
下面用DES对称加密算法(设定一个密钥,然后对所有的数据进行加密)来简单举个例子. 首先,生成一个密钥KEY. 我把它保存到key.txt中.这个文件就象是一把钥匙.谁拥有它,谁就能解开我们的类文件. ...
- Java加密解密相关
关于解释加密解密中的填充方案: http://laokaddk.blog.51cto.com/368606/461279/ 关于对称加密中的反馈模式: http://blog.csdn.net/aaa ...
- Java加密解密字符串
http://www.cnblogs.com/vwpolo/archive/2012/07/18/2597232.html Java加密解密字符串 旧文重发:http://www.blogjava ...
- Java加密解密大全
ChinaSEI系列讲义(By 郭克华) Java加密解密方法大全 如果有文字等小错,请多包涵.在不盈利的情况下,欢迎免费传播. 版权所有.郭克华 本讲义经 ...
- ◆JAVA加密解密-3DES
从数据安全谈起 当你使用网银时,是否担心你的银行卡会被盗用? 当你和朋友用QQ进行聊天时,是否担心你的隐私会被泄露? 作为开发者,编写安全的代码比编写优雅的代码更重要,因为 ...
- java加密解密的学习
注:此文章只是对如何学习java加密解密技术做一个讲解.并不涉及具体的知识介绍,如果有需要请留言,有时间我补冲长.个人觉着学习一个学习方法比学习一个知识点更有价值的多. 首先,对于加密解密知识体系没有 ...
- java加密解密
java加密解密 public class MD5Util { /** * @param args */ public static void main(String[] args) { System ...
- password学4——Java 加密解密之消息摘要算法(MD5 SHA MAC)
Java 加密解密之消息摘要算法(MD5 SHA MAC) 消息摘要 消息摘要(Message Digest)又称为数字摘要(Digital Digest). 它是一个唯一相应一个消息或文本的固定长度 ...
- java加密解密算法位运算
一.实例说明 本实例通过位运算的异或运算符 “ ^ ” 把字符串与一个指定的值进行异或运算,从而改变每个字符串中字符的值,这样就可以得到一个加密后的字符串.当把加密后的字符串作为程序输入内容,异或运算 ...
随机推荐
- 通过Rancher Desktop在桌面上运行K8s
Rancher 发行的操作系统新选择:Rancher Desktop for Windows,它可以帮助你在Windows桌面上管理Kubernetes和容器.当然他当然会支持Linux,Mac的. ...
- versions-maven-plugin插件批量修改版本号
1.简介 versions-maven-plugin插件可以管理项目版本, 特别是当Maven工程项目中有大量子模块时, 可以批量修改pom版本号, 插件会把父模块更新到指定版本号, 然后更新子模块版 ...
- 使用docker或者docker-compose部署Zookeeper集群
之前有介绍过Zookeeper的安装部署(Zookeeper基础教程(二):Zookeeper安装),但是那里我是基于独立的虚拟机来实现部署的,这种部署方式适合线上集群部署.后来有几次想用一下Zook ...
- docker容器的本质
1. 容器其实就是Linux下一个特殊的进程: 2. Docker容器通过namespace实现进程隔离通过cgroups实现资源限制: 3. Docker镜像(rootfs)是一个操作系统的所有文件 ...
- 初识python 之 ImportError: No module named _ssl
场景 安装好python之后,导入ssl模块报错: ImportError: No module named _ssl 解决方法 查看openssl.openssl-devel是否安装 rpm -qa ...
- java 方法 compareTo()的正确使用
总结:(1)如果比较的是数字 则结果大于则为1 等于则为0 小于则为-1(2)如果比较的是字符[串] 则按照从左到右排序找对应不一样的字符第一个字符, 然后将字符装对应的ASCLL码数字,做减法运算, ...
- java 封装 总结
1.前言 老是被问什么是java 封装...很基础的一个问题 ,其实我们一直在写的东西但不知道怎么称呼. 比如 在entity实体类 里面老用到的 getter 和 setter 方法其实就是封装的方 ...
- echarts-gl初体验:使用echarts-gl实现3D地球
首先我们要下载引入echarts.js和echarts-gl.js 有需要的自己拿资源哈 链接:https://pan.baidu.com/s/1J7U79ey-2ZN4pjb7RTarjg 提取码: ...
- 《剑指offer》面试题57 - II. 和为s的连续正数序列
问题描述 输入一个正整数 target ,输出所有和为 target 的连续正整数序列(至少含有两个数). 序列内的数字由小到大排列,不同序列按照首个数字从小到大排列. 示例 1: 输入:target ...
- Solon Web 开发,十一、国际化
Solon Web 开发 一.开始 二.开发知识准备 三.打包与运行 四.请求上下文 五.数据访问.事务与缓存应用 六.过滤器.处理.拦截器 七.视图模板与Mvc注解 八.校验.及定制与扩展 九.跨域 ...