Java 加解密技术系列之 DES
序
这篇文章,以及后面几篇。打算介绍几个对称加密算法。比方:DES、3DES(TripleDES)、AES 等。那么,这篇文章主要是对 DES 大概讲一下。
背景
对称加密算法的特点是算法公开、计算量小。不足之处是,交易两方都使用相同钥匙,安全性得不到保证。
概念
因此,今天专门来研究研究这个东西。
明文按 64 位进行分组,密钥长 64 位,密钥其实是 56 位參与 DES 运算(第8、16、24、32、40、48、56、64
位是校验位, 使得每一个密钥都有奇数个 1)分组后的明文组和 56 位的密钥按位替代或交换的方法形成密文组的加密方法。
基本原理
实际运用中,密钥仅仅用到了
64 位中的 56 位,这样才具有高的安全性。
主要流程
- 初始置换
D49 …… D7。
- 逆置换
分组模式
- ECB模式
然后每组都用同样的密钥加密,比方 DES 算法。假设最后一个分组长度不够 64 位,要补齐 64 位。
如图所看到的:
- CBC模式
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaGFwcHlsZWU2Njg4/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">
- CFB模式
他的特点是。每次加密的 Pi 和 Ci 不大于 64 位;加密算法和解密算法同样。不能适用于公钥算法。使用同样的密钥和初始向量的时候。同样明文使用 CFB 模式加密输出同样的密文。能够使用不同的初始化变量使同样的明文产生不同的密文。防止字典攻击。加密强度依赖于密钥长度;加密块长度过小时,会添加循环的数量,导致开销添加;加密块长度应时
8 位的整数倍(即字节为单位);一旦某位数据出错,会影响眼下和其后 8 个块的数据。
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaGFwcHlsZWU2Njg4/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">
- OFB模式
- CTR模式
代码实现
<span style="font-family:Comic Sans MS;"><span style="font-size:12px;">package com.sica.des; import com.google.common.base.Strings;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder; import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException; /**
* Created by xiang.li on 2015/2/28.
* DES 加解密工具类
*
* <pre>
* 支持 DES、DESede(TripleDES,就是3DES)、AES、Blowfish、RC2、RC4(ARCFOUR)
* DES key size must be equal to 56
* DESede(TripleDES) key size must be equal to 112 or 168
* AES key size must be equal to 128, 192 or 256,but 192 and 256 bits may not be available
* Blowfish key size must be multiple of 8, and can only range from 32 to 448 (inclusive)
* RC2 key size must be between 40 and 1024 bits
* RC4(ARCFOUR) key size must be between 40 and 1024 bits
* 详细内容 须要关注 JDK Document http://.../docs/technotes/guides/security/SunProviders.html
* </pre>
*/
public class DES {
/**
* 定义加密方式
*/
private final static String KEY_DES = "DES";
private final static String KEY_AES = "AES"; // 測试 /**
* 全局数组
*/
private final static String[] hexDigits = { "0", "1", "2", "3", "4", "5",
"6", "7", "8", "9", "a", "b", "c", "d", "e", "f" }; /**
* 初始化密钥
* @return
*/
public static String init() {
return init(null);
} /**
* 初始化密钥
* @param seed 初始化參数
* @return
*/
public static String init(String seed) {
SecureRandom secure = null;
String str = "";
try {
if (null != secure) {
// 带參数的初始化
secure = new SecureRandom(decryptBase64(seed));
} else {
// 不带參数的初始化
secure = new SecureRandom();
} KeyGenerator generator = KeyGenerator.getInstance(KEY_DES);
generator.init(secure); SecretKey key = generator.generateKey();
str = encryptBase64(key.getEncoded());
} catch (Exception e) {
e.printStackTrace();
}
return str;
} /**
* 转换密钥
* @param key 密钥的字节数组
* @return
*/
private static Key byteToKey(byte[] key) {
SecretKey secretKey = null;
try {
DESKeySpec dks = new DESKeySpec(key);
SecretKeyFactory factory = SecretKeyFactory.getInstance(KEY_DES);
secretKey = factory.generateSecret(dks); // 当使用其它对称加密算法时,如AES、Blowfish等算法时,用下述代码替换上述三行代码
// secretKey = new SecretKeySpec(key, KEY_DES);
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeySpecException e) {
e.printStackTrace();
}
return secretKey;
} /**
* DES 解密
* @param data 须要解密的字符串
* @param key 密钥
* @return
*/
public static String decryptDES(String data, String key) {
// 验证传入的字符串
if (Strings.isNullOrEmpty(data)) {
return "";
}
// 调用解密方法完毕解密
byte[] bytes = decryptDES(hexString2Bytes(data), key);
// 将得到的字节数组变成字符串返回
return new String(bytes);
} /**
* DES 解密
* @param data 须要解密的字节数组
* @param key 密钥
* @return
*/
public static byte[] decryptDES(byte[] data, String key) {
byte[] bytes = null;
try {
Key k = byteToKey(decryptBase64(key));
Cipher cipher = Cipher.getInstance(KEY_DES);
cipher.init(Cipher.DECRYPT_MODE, k);
bytes = cipher.doFinal(data);
} catch (Exception e) {
e.printStackTrace();
}
return bytes;
} /**
* DES 加密
* @param data 须要加密的字符串
* @param key 密钥
* @return
*/
public static String encryptDES(String data, String key) {
// 验证传入的字符串
if (Strings.isNullOrEmpty(data)) {
return "";
}
// 调用加密方法完毕加密
byte[] bytes = encryptDES(data.getBytes(), key);
// 将得到的字节数组变成字符串返回
return byteArrayToHexString(bytes);
} /**
* DES 加密
* @param data 须要加密的字节数组
* @param key 密钥
* @return
*/
public static byte[] encryptDES(byte[] data, String key) {
byte[] bytes = null;
try {
Key k = byteToKey(decryptBase64(key));
Cipher cipher = Cipher.getInstance(KEY_DES);
cipher.init(Cipher.ENCRYPT_MODE, k);
bytes = cipher.doFinal(data);
} catch (Exception e) {
e.printStackTrace();
}
return bytes;
} /**
* BASE64 解密
* @param key 须要解密的字符串
* @return 字节数组
* @throws Exception
*/
public static byte[] decryptBase64(String key) throws Exception {
return (new BASE64Decoder()).decodeBuffer(key);
} /**
* BASE64 加密
* @param key 须要加密的字节数组
* @return 字符串
* @throws Exception
*/
public static String encryptBase64(byte[] key) throws Exception {
return (new BASE64Encoder()).encodeBuffer(key);
} /**
* 将一个字节转化成十六进制形式的字符串
* @param b 字节数组
* @return 字符串
*/
private static String byteToHexString(byte b) {
int ret = b;
//System.out.println("ret = " + ret);
if (ret < 0) {
ret += 256;
}
int m = ret / 16;
int n = ret % 16;
return hexDigits[m] + hexDigits[n];
} /**
* 转换字节数组为十六进制字符串
* @param bytes 字节数组
* @return 十六进制字符串
*/
private static String byteArrayToHexString(byte[] bytes) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < bytes.length; i++) {
sb.append(byteToHexString(bytes[i]));
}
return sb.toString();
} /**
* 转换十六进制字符串为字节数组
* @param hexstr 十六进制字符串
* @return
*/
public static byte[] hexString2Bytes(String hexstr) {
byte[] b = new byte[hexstr.length() / 2];
int j = 0;
for (int i = 0; i < b.length; i++) {
char c0 = hexstr.charAt(j++);
char c1 = hexstr.charAt(j++);
b[i] = (byte) ((parse(c0) << 4) | parse(c1));
}
return b;
} /**
* 转换字符类型数据为整型数据
* @param c 字符
* @return
*/
private static int parse(char c) {
if (c >= 'a')
return (c - 'a' + 10) & 0x0f;
if (c >= 'A')
return (c - 'A' + 10) & 0x0f;
return (c - '0') & 0x0f;
} /**
* 測试方法
* @param args
*/
public static void main(String[] args) {
String key = DES.init();
System.out.println("DES密钥:\n" + key); String word = "123"; String encWord = encryptDES(word, key); System.out.println(word + "\n加密后:\n" + encWord);
System.out.println(word + "\n解密后:\n" + decryptDES(encWord, key));
}
}</span><span style="font-size: 14px;">
</span></span>
结束语
Java 加解密技术系列之 DES的更多相关文章
- 5.Java 加解密技术系列之 DES
Java 加解密技术系列之 DES 序 背景 概念 基本原理 主要流程 分组模式 代码实现 结束语 序 前 几篇文章讲的都是单向加密算法,其中涉及到了 BASE64.MD5.SHA.HMAC 等几个比 ...
- Java 加解密技术系列文章
Java 加解密技术系列之 总结 Java 加解密技术系列之 DH Java 加解密技术系列之 RSA Java 加解密技术系列之 PBE Java 加解密技术系列之 AES Java 加解密技术系列 ...
- 10.Java 加解密技术系列之 DH
Java 加解密技术系列之 DH 序 概念 原理 代码实现 结果 结束语 序 上一篇文章中简单的介绍了一种非对称加密算法 — — RSA,今天这篇文章,继续介绍另一种非对称加密算法 — — DH.当然 ...
- 8.Java 加解密技术系列之 PBE
Java 加解密技术系列之 PBE 序 概念 原理 代码实现 结束语 序 前 边的几篇文章,已经讲了几个对称加密的算法了,今天这篇文章再介绍最后一种对称加密算法 — — PBE,这种加密算法,对我的认 ...
- 7.java 加解密技术系列之 AES
java 加解密技术系列之 AES 序 概念 原理 应用 代码实现 结束语 序 这篇文章继续介绍对称加密算法,至于今天的主角,不用说,也是个厉害的角色 — — AES.AES 的出现,就是为了来替代原 ...
- 6. Java 加解密技术系列之 3DES
Java 加解密技术系列之 3DES 序 背景 概念 原理 代码实现 结束语 序 上一篇文章讲的是对称加密算法 — — DES,这篇文章打算在 DES 的基础上,继续多讲一点,也就是 3 重 DES ...
- 11.Java 加解密技术系列之 总结
Java 加解密技术系列之 总结 序 背景 分类 常用算法 原理 关于代码 结束语 序 上一篇文章中简单的介绍了第二种非对称加密算法 — — DH,这种算法也经常被叫做密钥交换协议,它主要是针对密钥的 ...
- 9.Java 加解密技术系列之 RSA
Java 加解密技术系列之 RSA 序 概念 工作流程 RSA 代码实现 加解密结果 结束语 序 距 离上一次写博客感觉已经很长时间了,先吐槽一下,这个月以来,公司一直在加班,又是发版.上线,又是新项 ...
- 4.Java 加解密技术系列之 HMAC
Java 加解密技术系列之 HMAC 序 背景 正文 代码 结束语 序 上一篇文章中简单的介绍了第二种单向加密算法 — —SHA,同时也给出了 SHA-1 的 Java 代码.有这方面需求的童鞋可以去 ...
随机推荐
- 安装淘宝内核LVS
具体安装方法按照淘宝twiki来:http://kernel.taobao.org/index.php?title=Documents/Kernel_build. 但是有些问题是要注意的: 1. 修改 ...
- 论文笔记《Fully Convolutional Networks for Semantic Segmentation》
一.Abstract 提出了一种end-to-end的做semantic segmentation的方法,也就是FCN,是我个人觉得非常厉害的一个方法. 二.亮点 1.提出了全卷积网络的概念,将Ale ...
- Python(2)-- 运算符
1. 算术运算符 常规: 加(+).减(-).乘(*).除(/).取模(%) 此外: 幂(**):返回x的y次幂, eg: 2**3---返回 2 的 5 次幂,输出结果32 取整除(//):返回商的 ...
- HTML 上标和下标
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
- [转].net创建XML文件的两种方法
原文发布时间为:2009-08-26 -- 来源于本人的百度文章 [由搬家工具导入] 方法一:按照XML的结构一步一步的构建XML文档. 通过.Net FrameWork SDK中的命名空间&q ...
- C#获取二维数组的行数和列数及其多维。。。
原文发布时间为:2008-11-26 -- 来源于本人的百度文章 [由搬家工具导入] 有一个二维数组sz[,] 怎样获取sz 的行数和列数呢? sz.GetLength(0) 返回第一维的长度(即行数 ...
- JS - caller,callee,call,apply [transfer] aA ==> apply uses an array [] as the second argument. call uses different argument.
在提到上述的概念之前,首先想说说javascript中函数的隐含参数:arguments Arguments : 该对象代表正在执行的函数和调用它的函数的参数. [function.]argument ...
- C 语言 和 python 调用 .so 文件
什么是静态库和动态库, 看一篇博客 http://www.cnblogs.com/skynet/p/3372855.html 现在,我们首先生成.so文件 首先, 我们写一个a.c文件 1 2 3 4 ...
- C#Qrcode生成二维码支持中文,带图片,带文字
C#Qrcode生成二维码支持中文带图片的操作请看二楼的帖子,当然开始需要下载一下C#Qrcode的源码 下载地址 : http://www.codeproject.com/Articles/2057 ...
- ios 地图,系统升级为12后,进入地图,大头针全部默认展开问题,以及在选择不同距离的情况下,如何刷新地图的区域范围
1.第一个问题,大头针在ios12,默认展开问题,需要设置大头针视图的默认选中属性为NO - (MKAnnotationView *)mapView:(MKMapView *)mapView view ...