转自李祥:http://blog.csdn.net/happylee6688/article/details/44455407
Java 加解密技术系列之 DES
标签: 加密解密技术des
2015-03-19 12:04 5093人阅读 收藏 举报
版权声明:本文为博主原创文章,未经博主允许不得转载。
目录(?)[-]
- 序
- 背景
- 概念
- 基本原理
- 主要流程
- 分组模式
- 代码实现
- 结束语
序
前几篇文章讲的都是单向加密算法,其中涉及到了 BASE64、MD5、SHA、HMAC 等几个比较常见的加解密算法。这篇文章,以及后面几篇,打算介绍几个对称加密算法,比如:DES、3DES(TripleDES)、AES 等。那么,这篇文章主要是对 DES 大概讲一下。
背景
在讨论 DES 之前,首先了解一下什么是对称加密算法吧。对于对称加密算法,他应用的时间比较早,技术相对来说比较成熟,在对称加密算法中,数据发信方将明文(原始数据)和加密密钥一起经过特殊加密算法处理后,使其变成复杂的加密密文发送出去。收信方收到密文后,若想解读原文,则需要使用加密用过的密钥及相同算法的逆算法对密文进行解密,才能使其恢复成可读明文。
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 加解密工具类** * 支持 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*
*/
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 &#61; new SecretKeySpec(key, KEY_DES);} catch (InvalidKeyException e) {e.printStackTrace();} catch (NoSuchAlgorithmException e) {e.printStackTrace();} catch (InvalidKeySpecException e) {e.printStackTrace();}return secretKey;}/*** DES 解密* &#64;param data 需要解密的字符串* &#64;param key 密钥* &#64;return*/public static String decryptDES(String data, String key) {// 验证传入的字符串if (Strings.isNullOrEmpty(data)) {return "";}// 调用解密方法完成解密byte[] bytes &#61; decryptDES(hexString2Bytes(data), key);// 将得到的字节数组变成字符串返回return new String(bytes);}/*** DES 解密* &#64;param data 需要解密的字节数组* &#64;param key 密钥* &#64;return*/public static byte[] decryptDES(byte[] data, String key) {byte[] bytes &#61; null;try {Key k &#61; byteToKey(decryptBase64(key));Cipher cipher &#61; Cipher.getInstance(KEY_DES);cipher.init(Cipher.DECRYPT_MODE, k);bytes &#61; cipher.doFinal(data);} catch (Exception e) {e.printStackTrace();}return bytes;}/*** DES 加密* &#64;param data 需要加密的字符串* &#64;param key 密钥* &#64;return*/public static String encryptDES(String data, String key) {// 验证传入的字符串if (Strings.isNullOrEmpty(data)) {return "";}// 调用加密方法完成加密byte[] bytes &#61; encryptDES(data.getBytes(), key);// 将得到的字节数组变成字符串返回return byteArrayToHexString(bytes);}/*** DES 加密* &#64;param data 需要加密的字节数组* &#64;param key 密钥* &#64;return*/public static byte[] encryptDES(byte[] data, String key) {byte[] bytes &#61; null;try {Key k &#61; byteToKey(decryptBase64(key));Cipher cipher &#61; Cipher.getInstance(KEY_DES);cipher.init(Cipher.ENCRYPT_MODE, k);bytes &#61; cipher.doFinal(data);} catch (Exception e) {e.printStackTrace();}return bytes;}/*** BASE64 解密* &#64;param key 需要解密的字符串* &#64;return 字节数组* &#64;throws Exception*/public static byte[] decryptBase64(String key) throws Exception {return (new BASE64Decoder()).decodeBuffer(key);}/*** BASE64 加密* &#64;param key 需要加密的字节数组* &#64;return 字符串* &#64;throws Exception*/public static String encryptBase64(byte[] key) throws Exception {return (new BASE64Encoder()).encodeBuffer(key);}/*** 将一个字节转化成十六进制形式的字符串* &#64;param b 字节数组* &#64;return 字符串*/private static String byteToHexString(byte b) {int ret &#61; b;//System.out.println("ret &#61; " &#43; ret);if (ret <0) {ret &#43;&#61; 256;}int m &#61; ret / 16;int n &#61; ret % 16;return hexDigits[m] &#43; hexDigits[n];}/*** 转换字节数组为十六进制字符串* &#64;param bytes 字节数组* &#64;return 十六进制字符串*/private static String byteArrayToHexString(byte[] bytes) {StringBuffer sb &#61; new StringBuffer();for (int i &#61; 0; i &#61; &#39;a&#39;)return (c - &#39;a&#39; &#43; 10) & 0x0f;if (c >&#61; &#39;A&#39;)return (c - &#39;A&#39; &#43; 10) & 0x0f;return (c - &#39;0&#39;) & 0x0f;}/*** 测试方法* &#64;param args*/public static void main(String[] args) {String key &#61; DES.init();System.out.println("DES密钥:\n" &#43; key);String word &#61; "123";String encWord &#61; encryptDES(word, key);System.out.println(word &#43; "\n加密后&#xff1a;\n" &#43; encWord);System.out.println(word &#43; "\n解密后&#xff1a;\n" &#43; decryptDES(encWord, key));}
}