标签:img 相同 收信 避免 trace pen ret 单位 .net
这篇文章,以及后面几篇。打算介绍几个对称加密算法。比方:DES、3DES(TripleDES)、AES 等。那么,这篇文章主要是对 DES 大概讲一下。
对称加密算法的特点是算法公开、计算量小。不足之处是,交易两方都使用相同钥匙,安全性得不到保证。
因此,今天专门来研究研究这个东西。
明文按 64 位进行分组,密钥长 64 位,密钥其实是 56 位參与 DES 运算(第8、16、24、32、40、48、56、64 位是校验位, 使得每一个密钥都有奇数个 1)分组后的明文组和 56 位的密钥按位替代或交换的方法形成密文组的加密方法。
实际运用中,密钥仅仅用到了 64 位中的 56 位,这样才具有高的安全性。
然后每组都用同样的密钥加密,比方 DES 算法。假设最后一个分组长度不够 64 位,要补齐 64 位。
如图所看到的:
他的特点是。每次加密的 Pi 和 Ci 不大于 64 位;加密算法和解密算法同样。不能适用于公钥算法。使用同样的密钥和初始向量的时候。同样明文使用 CFB 模式加密输出同样的密文。能够使用不同的初始化变量使同样的明文产生不同的密文。防止字典攻击。加密强度依赖于密钥长度;加密块长度过小时,会添加循环的数量,导致开销添加;加密块长度应时 8 位的整数倍(即字节为单位);一旦某位数据出错,会影响眼下和其后 8 个块的数据。
<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>
标签:img 相同 收信 避免 trace pen ret 单位 .net
原文地址:http://www.cnblogs.com/claireyuancy/p/6789292.html