◆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加密解密算法位运算
一.实例说明 本实例通过位运算的异或运算符 “ ^ ” 把字符串与一个指定的值进行异或运算,从而改变每个字符串中字符的值,这样就可以得到一个加密后的字符串.当把加密后的字符串作为程序输入内容,异或运算 ...
随机推荐
- MySQL客户端mysql常用命令
通过MySQL自带的mysql命令行工具, 执行MySQL的相关命令. 1.连接MySQL服务端 mysql -uUserName -pPassword -h HostName_IP -P 3306 ...
- Python中*args 和**kwargs作为形参和实参时的功能详解
*args 和**kwargs作为形参 *args 和**kwargs作为形参被称为不定长参数,用来处理超出必备参数部分的参数.注意:args和kwargs可以修改为其它变量名. 必备参数就是在定义函 ...
- Hive建表和内外部表的使用
原文链接: https://www.toutiao.com/i6766784274965201415 一.普通建表方式 create table stu_info( id int, name stri ...
- springboot集成oss阿里云存储
一.注册阿里云 二.购买OSS 三.创建桶 设定权限,其它默认即可 四.创建目录 点击桶名,进入创建目录即可. 五.开发文档 引入依赖: <dependency> <groupId& ...
- LCT小记
不用说了,直接上怎么 die( 千万不要和 Treap 一样写左旋 zig 和右旋 zag,莫名死亡.Splay 只支持一个 rotate 上旋一个节点即可. splay() 之前记得弄一个栈存储 u ...
- 【记录一个问题】libtask无法在android下编译通过
源码来自:https://github.com/msteinert/libtask 首先是asm.S无法编译通过. 其次,编译context.c出现这些错误: .//context.c:124:19: ...
- Choregraphe 2.8.6.23虚拟Nao机器人Socket is not connected
Traceback (most recent call last): File "c:/Users/fengmao/OneDrive - University of Wollongong/J ...
- IPV4地址,子网掩码,子网划分
转载自https://blog.csdn.net/qq_45108415/article/details/114179407
- 关于BIO NIO和AIO的理解
转载自 :http://blog.csdn.net/anxpp/article/details/51512200 1.BIO编程 1.1.传统的BIO编程 网络编程的基本模型是C/S模型,即两个进程间 ...
- 43.Kruskal算法
public class KruskalCase { private int edgeNum; //边的个数 private char[] vertexs; //顶点数组 private int[][ ...