DES —— JAVA代码
二话不说,先把代码实现再学习原理!
普通DES代码如下
1import javax.crypto.Cipher; 2import javax.crypto.KeyGenerator; 3import javax.crypto.SecretKey; 4import javax.crypto.SecretKeyFactory; 5import javax.crypto.spec.DESKeySpec; 6import java.security.InvalidKeyException; 7import java.security.Key; 8import java.security.NoSuchAlgorithmException; 9import java.util.Base64; 10 11/** 12 * @author : R&M www.rmworking.com/blog 13 * 2019/8/18 14:40 14 * jsoup_demo 15 * org.security.utils 16 */ 17public class DESUtil { 18 public static void main(String[] args) throws Exception { 19 // 需要加密的数据 20 String str = "qnloft.com(青柠Loft)"; 21 // 初始化密匙 22 byte[] key = DESUtil.initKey(); 23 System.out.println("密匙:" + Base64.getEncoder().encodeToString(key)); 24 // 加密 25 byte[] encryptData = DESUtil.encrypt(str.getBytes(), key); 26 System.out.println("加密结果:" + Base64.getEncoder().encodeToString(encryptData)); 27 // 解密 28 String resutl = new String(DESUtil.decrypt(encryptData, key)); 29 System.out.println("解密结果:" + resutl); 30 } 31 32 private static final String KEY_ALGORITHM = "DES"; 33 /** 34 * 加解密算法/工作模式/填充方式 35 */ 36 private static final String CIPHER_ALGORITHM_PKCS5 = "DES/ECB/PKCS5Padding"; 37 38 /** 39 * 生成密匙 40 * @return 41 * @throws NoSuchAlgorithmException 42 */ 43 public static byte[] initKey() throws NoSuchAlgorithmException { 44 // 实例化密匙生成器 45 KeyGenerator kg = KeyGenerator.getInstance(KEY_ALGORITHM); 46 // 初始化密匙生成器 47 kg.init(56); 48 // 生成密匙 49 SecretKey secretKey = kg.generateKey(); 50 // 二进制形式返回密匙 51 return secretKey.getEncoded(); 52 } 53 54 /** 55 * 加密 56 * @param data 57 * @param key 58 * @return 59 */ 60 public static byte[] encrypt(byte[] data, byte[] key) throws Exception { 61 // 还原密匙 62 Key k = toKey(key); 63 // 实例化 64 Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM_PKCS5); 65 // 初始化,设置为解密模式 66 cipher.init(Cipher.ENCRYPT_MODE, k); 67 // 执行操作 68 return cipher.doFinal(data); 69 } 70 71 /** 72 * 解密 73 * @param data 74 * @param key 75 * @return 76 * @throws Exception 77 */ 78 public static byte[] decrypt(byte[] data, byte[] key) throws Exception { 79 // 还原密匙 80 Key k = toKey(key); 81 // 实例化 82 Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM_PKCS5); 83 // 初始化,设置为解密模式 84 cipher.init(Cipher.DECRYPT_MODE, k); 85 // 执行操作 86 return cipher.doFinal(data); 87 } 88 89 /** 90 * 转换密匙 91 * @param key 92 * @return 93 * @throws InvalidKeyException 94 */ 95 private static Key toKey(byte[] key) throws Exception { 96 // 实例化DES密匙材料 97 DESKeySpec desKeySpec = new DESKeySpec(key); 98 // 实例化密匙工厂 99 SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(KEY_ALGORITHM); 100 // 生成密匙 101 return keyFactory.generateSecret(desKeySpec); 102 } 103 104}
三重DES代码如下
1import javax.crypto.Cipher; 2import javax.crypto.KeyGenerator; 3import javax.crypto.SecretKey; 4import javax.crypto.SecretKeyFactory; 5import javax.crypto.spec.DESedeKeySpec; 6import java.security.InvalidKeyException; 7import java.security.Key; 8import java.security.NoSuchAlgorithmException; 9import java.util.Base64; 10 11/** 12 * @author : R&M www.rmworking.com/blog 13 * 2019/8/25 17:28 14 * jsoup_demo 15 * org.security.utils 16 */ 17public class DESEdeUtil { 18 public static void main(String[] args) throws Exception { 19 // 需要加密的数据 20 String str = "qnloft.com(青柠Loft)"; 21 // 初始化密匙 22 byte[] key = DESEdeUtil.initKey(); 23 System.out.println("密匙:" + Base64.getEncoder().encodeToString(key)); 24 // 加密 25 byte[] encryptData = DESEdeUtil.encrypt(str.getBytes(), key); 26 System.out.println("加密结果:" + Base64.getEncoder().encodeToString(encryptData)); 27 // 解密 28 String resutl = new String(DESEdeUtil.decrypt(encryptData, key)); 29 System.out.println("解密结果:" + resutl); 30 } 31 32 private static final String KEY_ALGORITHM = "DESede"; 33 /** 34 * 加解密算法/工作模式/填充方式 35 * 36 * 数据补位一般有NoPadding和PKCS7Padding(JAVA中是PKCS5Padding)填充方式 37 */ 38 private static final String CIPHER_ALGORITHM_PKCS5 = "DESede/ECB/PKCS5Padding"; 39 40 /** 41 * 生成密匙 42 * @return 43 * @throws NoSuchAlgorithmException 44 */ 45 public static byte[] initKey() throws NoSuchAlgorithmException { 46 // 实例化密匙生成器 47 KeyGenerator kg = KeyGenerator.getInstance(KEY_ALGORITHM); 48 // 初始化密匙生成器 49 kg.init(168); 50 // 生成密匙 51 SecretKey secretKey = kg.generateKey(); 52 // 二进制形式返回密匙 53 return secretKey.getEncoded(); 54 } 55 56 /** 57 * 加密 58 * @param data 59 * @param key 60 * @return 61 */ 62 public static byte[] encrypt(byte[] data, byte[] key) throws Exception { 63 // 还原密匙 64 Key k = toKey(key); 65 // 实例化 66 Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM_PKCS5); 67 // 初始化,设置为解密模式 68 cipher.init(Cipher.ENCRYPT_MODE, k); 69 // 执行操作 70 return cipher.doFinal(data); 71 } 72 73 /** 74 * 解密 75 * @param data 76 * @param key 77 * @return 78 * @throws Exception 79 */ 80 public static byte[] decrypt(byte[] data, byte[] key) throws Exception { 81 // 还原密匙 82 Key k = toKey(key); 83 // 实例化 84 Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM_PKCS5); 85 // 初始化,设置为解密模式 86 cipher.init(Cipher.DECRYPT_MODE, k); 87 // 执行操作 88 return cipher.doFinal(data); 89 } 90 91 /** 92 * 转换密匙 93 * @param key 94 * @return 95 * @throws InvalidKeyException 96 */ 97 private static Key toKey(byte[] key) throws Exception { 98 // 实例化DES密匙材料 99 DESedeKeySpec desKeySpec = new DESedeKeySpec(key); 100 // 实例化密匙工厂 101 SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(KEY_ALGORITHM); 102 // 生成密匙 103 return keyFactory.generateSecret(desKeySpec); 104 } 105}
DES填充方式说明:
NoPadding填充方式:算法本身不填充,PKCS5Padding填充方式:为JAVA的默认填充方式,对加密数据字节长度对8取余为r,如r大于0,则补8-r个字节,字节为8-r的值;如果r等于0,则补8个字节8。比如:加密字符串为为AAA,则补位为AAA55555;加密字符串为BBBBBB,则补位为BBBBBB22;加密字符串为CCCCCCCC,则补位为CCCCCCCC88888888。
DES —— 消息传递过程

- 甲方(发送者)生成密钥Key
- 将生成的key传给乙方
- 甲方使用密钥对字符串进行加密
- 甲方加加密后的字符串传给乙方
- 乙方根据密钥key对字符串进行解密操作
DES和DESEde —— 简介
DES全称为Data Encryption Standard,即数据加密标准,是一种使用密钥加密的块算法,1977年被美国联邦政府的国家标准局确定为联邦资料处理标准(FIPS),并授权在非密级政府通信中使用,随后该算法在国际上广泛流传开来。需要注意的是,在某些文献中,作为算法的DES称为数据加密算法(Data Encryption Algorithm,DEA),已与作为标准的DES区分开来。
1988年后,实例化DES算法破译机的出现,彻底宣告DES算法已经不具备安全性。
3DES(即Triple DES)是DES向AES过渡的加密算法,它使用3条56位的密钥对数据进行三次加密。是DES的一个更安全的变形。它以DES为基本模块,通过组合分组方法设计出分组加密算法。比起最初的DES,3DES更为安全。
DESEde使用两个密钥,执行三次DES算法,加密的过程是加密-解密-加密,解密的过程是解密-加密-解密。
- 3DES加密过程为:C=Ek3(Dk2(Ek1(P)))
- 3DES解密过程为:P=Dk1(EK2(Dk3(C)))
采用两个密钥进行三重加密的好处有:
- 两个密钥合起来有效密钥长度有112bit,可以满足商业应用的需要,若采用总长为168bit的三个密钥,会产生不必要的开销。
- 加密时采用加密-解密-加密,而不是加密-加密-加密的形式,这样有效的实现了与现有DES系统的向后兼容问题。因为当K1=K2时,三重DES的效果就和原来的DES一样,有助于逐渐推广三重DES。
- 三重DES具有足够的安全性,目前还没有关于攻破3DES的报道。
密匙比较:
1DES密匙: be+SuW5Jnc0= 2DESEde密匙:JrkV4N/TXRlkZHP3Aj1h38TCitlRvz1R
从密匙长度我们可以看出三重DES的缺点就是解密的速度会比DES慢很多,时间换安全也是非常值得的事情。
DES —— 算法实现
DES算法把64位的明文输入块变为64位的密文输出块,它所使用的密钥也是64位(实际用到了56位,第8、16、24、32、40、48、56、64位是校验位, 使得每个密钥都有奇数个1),其算法主要分为两步:
1.) 初始置换

其功能是把输入的64位数据块按位重新组合,并把输出分为L0、R0两部分,每部分各长32位,其置换规则为将输入的第58位换到第一位,第50位换到第2位……依此类推,最后一位是原来的第7位。L0、R0则是换位输出后的两部分,L0是输出的左32位,R0是右32位,例:设置换前的输入值为D1D2D3……D64,则经过初始置换后的结果为:L0=D58D50……D8;R0=D57D49……D7。
其置换规则见下表:
58,50,42,34,26,18,10,2,
60,52,44,36,28,20,12,4,
62,54,46,38,30,22,14,6,
64,56,48,40,32,24,16,8,
57,49,41,33,25,17,9,1,
59,51,43,35,27,19,11,3,
61,53,45,37,29,21,13,5,
63,55,47,39,31,23,15,7,
2.) 逆置换

经过16次迭代运算后,得到L16、R16,将此作为输入,进行逆置换,逆置换正好是初始置换的逆运算,由此即得到密文输出
--Posted from Rpc