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的更多相关文章

  1. JAVA加密解密DES对称加密算法

    下面用DES对称加密算法(设定一个密钥,然后对所有的数据进行加密)来简单举个例子. 首先,生成一个密钥KEY. 我把它保存到key.txt中.这个文件就象是一把钥匙.谁拥有它,谁就能解开我们的类文件. ...

  2. Java加密解密相关

    关于解释加密解密中的填充方案: http://laokaddk.blog.51cto.com/368606/461279/ 关于对称加密中的反馈模式: http://blog.csdn.net/aaa ...

  3. Java加密解密字符串

    http://www.cnblogs.com/vwpolo/archive/2012/07/18/2597232.html Java加密解密字符串   旧文重发:http://www.blogjava ...

  4. Java加密解密大全

    ChinaSEI系列讲义(By 郭克华)   Java加密解密方法大全                     如果有文字等小错,请多包涵.在不盈利的情况下,欢迎免费传播. 版权所有.郭克华 本讲义经 ...

  5. ◆JAVA加密解密-3DES

    从数据安全谈起       当你使用网银时,是否担心你的银行卡会被盗用?     当你和朋友用QQ进行聊天时,是否担心你的隐私会被泄露?     作为开发者,编写安全的代码比编写优雅的代码更重要,因为 ...

  6. java加密解密的学习

    注:此文章只是对如何学习java加密解密技术做一个讲解.并不涉及具体的知识介绍,如果有需要请留言,有时间我补冲长.个人觉着学习一个学习方法比学习一个知识点更有价值的多. 首先,对于加密解密知识体系没有 ...

  7. java加密解密

    java加密解密 public class MD5Util { /** * @param args */ public static void main(String[] args) { System ...

  8. password学4——Java 加密解密之消息摘要算法(MD5 SHA MAC)

    Java 加密解密之消息摘要算法(MD5 SHA MAC) 消息摘要 消息摘要(Message Digest)又称为数字摘要(Digital Digest). 它是一个唯一相应一个消息或文本的固定长度 ...

  9. java加密解密算法位运算

    一.实例说明 本实例通过位运算的异或运算符 “ ^ ” 把字符串与一个指定的值进行异或运算,从而改变每个字符串中字符的值,这样就可以得到一个加密后的字符串.当把加密后的字符串作为程序输入内容,异或运算 ...

随机推荐

  1. 编写Java程序,使用Swing布局管理器和常用控件,实现仿QQ登录界面

    返回本章节 返回作业目录 需求说明: 使用Swing布局管理器和常用控件,实现仿QQ登录界面 实现思路: 创建登录界面的类QQLogin,该类继承父类JFrame,在该类中创建无参数的构造方法,在构造 ...

  2. java并发系列——底层CPU

    java并发有诸多难点,实际上并非java语言本身的问题,本质上说一部分是因为并发操作本身的问题,另外一部分是因为计算机体系结构带来的.为了更好地理解java并发过程中的问题,我们应该对CPU有一些基 ...

  3. k8s loadbalancer与ingress实践

    k8s可以通过三种方式将集群内服务暴露到外网,分别是NodePort.LoadBalancer.Ingress,其中NodePort作为基础通信形式我们在<k8s网络模型与集群通信>中进行 ...

  4. .net core中Grpc使用报错:The response ended prematurely.

    当我们调用Grpc是出现下面的一堆异常时,一般是由于LTS导致的: Call failed with gRPC error status. Status code: 'Unavailable', Me ...

  5. Nginx日志配置及日志分析脚本案例

    https://blog.csdn.net/bbwangj/article/details/82186162 nginx的log日志分为access log 和 error log 其中access ...

  6. Kubernetes三大落地姿势,你pick谁?

    Kubernetes是面向企业的开源容器编排工具的事实标准,它提供了应用部署.扩展.容器管理等功能.经过几年的发展,Kubernetes已成为云计算和现代IT基础架构的通用平台,得到广泛应用进入产业落 ...

  7. JNDI和JDBC的区别

    最近也是遇见了JNDI这个概念,查了一下,网上的说法太官方,所以参考下一位老哥的博客总结下 JDBC 看到最多的就是,Java Database Connectivity (JDBC)是一个标准的Ja ...

  8. Flink SQL任务自动生成与提交

    目录 起因 思路 实现 1.配置 2.界面如下 3.环境 问题 起因 事情的起因,是看到一篇公众号文章Apache Flink 在汽车之家的应用与实践,里面提到了"基于 SQL 的开发流程& ...

  9. postman设置token等关联参数

    登陆时登录成功后服务器会返回一个token,这个token作为第二步骤的入参:第二个步骤请求成功后服务器会返回一个新token,然后这个token作为第三步骤的入参!如此一来的话,要用postman做 ...

  10. 自从学会了VBA字典,VLOOKUP都不那么香了

    上篇博文中,小爬曾多次为VBA字典带货.鼓励多用字典,可以让我们的VBA脚本工具执行更快.今天小爬来细聊一下VBA字典的具体应用!如果你有一定VBA基础,那么看完你一定会对VBA字典有全新的认识:如果 ...