DES - 对称加密算法简要介绍与JAVA实现(despite)

网友投稿 414 2022-10-01


DES - 对称加密算法简要介绍与JAVA实现(despite)

【1】DES简介

DES,全称为“Data Encryption Standard”,中文名为“数据加密标准”,是一种使用密钥加密的块算法,也是对称加密算法。

DES 算法为密码体制中的对称密码体制,又被称为美国数据加密标准,是 1972 年美国 IBM 公司研制的对称密码体制加密算法。

明文按 64 位进行分组,密钥长 64 位(8bytes=64bit),密钥事实上是 56 位参与 DES 运算(第8、16、24、32、40、48、56、64 位是校验位, 使得每个密钥都有奇数个 1)分组后的明文组和 56 位的密钥按位替代或交换的方法形成密文组的加密方法。

【2】分组模式

DES加密模式:有ECB、CBC、CFB、OFB、CTR等几种工作模式。

① ECB

ECB,中文名“电子密码本模式”,是最古老、最简单的模式,将加密的数据分成若干组,每组的大小跟加密密钥长度相同。然后每组都用相同的密钥加密,比如 DES 算法,如果最后一个分组长度不够 64 位,要补齐 64 位。

② CBC

CBC,中文名“加密块链模式”,与 ECB 模式最大的不同是加入了初始向量。

它的特点是,每次加密的密文长度为 64位 ( 8 个字节),当相同的明文使用相同的密钥和初始向量的时候 CBC 模式总是产生相同的密文。

③ CFB

CFB,中文名“加密反馈模式”,加密反馈模式克服了需要等待 8 个字节才能加密的缺点,它采用了分组密码作为流密码的密钥流生成器。

它的特点是,每次加密的 Pi 和 Ci 不大于 64 位;加密算法和解密算法相同,不能适用于公钥算法;使用相同的密钥和初始向量的时候,相同明文使用 CFB 模式加密输出相同的密文;可以使用不同的初始化变量使相同的明文产生不同的密文,防止字典攻击;加密强度依赖于密钥长度;加密块长度过小时,会增加循环的数量,导致开销增加;加密块长度应时 8 位的整数倍(即字节为单位);一旦某位数据出错,会影响目前和其后 8 个块的数据。

④ OFB

OFB,中文名“输出反馈模式”,与 CFB 模式不同之处在于, 加密位移寄存器与密文无关了,仅与加密 key 和加密算法有关。

做法是不再把密文输入到加密移位寄存器,而是把输出的分组密文(Oi)输入到一位寄存器。

因为密文没有参与链操作,所以使得 OFB 模式更容易受到攻击;不会进行错误传播,某位密文发生错误,只会影响该位对应的明文,而不会影响别的位;不是自同步的,如果加密和解密两个操作失去同步,那么系统需要重新初始化;每次重新同步时,应使用不同的初始向量。可以避免产生相同的比特流,避免“已知明文”攻击。

⑤ CTR

CTR,中文名“计数模式”,是对一系列输入数据块(称为计数)进行加密,产生一系列的输出块,输出块与明文异或得到密文。对于最后的数据块,可能是长 u 位的局部数据块,这 u 位就将用于异或操作,而剩下的 b-u 位将被丢弃(b表示块的长度)。

【3】Java实现

DesUtil如下:

package com.hh.common.encrypt;import javax.crypto.Cipher;import javax.crypto.SecretKey;import javax.crypto.SecretKeyFactory;import javax.crypto.spec.DESKeySpec;import javax.crypto.spec.IvParameterSpec;public class DesUtil { // 非对称加密算法 加密key 解密key 不相同 /** * 功能描述:DES加密方法。 * @param encryptString String类型 要加密的数据 * @param encryptKey String类型 加密的密钥 * @return byte[]类型 加密后结果 * */ public static byte[] encrypt(String encryptString, String encryptKey) { try { // 创建一个密匙工厂,然后用它把DESKeySpec转换成securekey SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); DESKeySpec desKey = new DESKeySpec(encryptKey.getBytes("UTF-8")); SecretKey securekey = keyFactory.generateSecret(desKey); // Cipher对象实际完成加密操作 Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding"); // 偏移量 IvParameterSpec iv = new IvParameterSpec(encryptKey.getBytes("UTF-8")); // 用密匙初始化Cipher对象 cipher.init(Cipher.ENCRYPT_MODE, securekey, iv); // 执行加密操作 return cipher.doFinal(encryptString.getBytes()); } catch (Exception e){ e.printStackTrace(); return null; } } /** * 功能描述:DES加密方法。 * base64(des(src,key)) * @param encryptString String类型 要加密的数据 * @param encryptKey String类型 加密的密钥 * @return byte[]类型 加密后结果 * */ public static String encryptBase64(String encryptString, String encryptKey) { try {// SecureRandom secureRandom = new SecureRandom(); // 创建一个密匙工厂,然后用它把DESKeySpec转换成securekey SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); DESKeySpec desKey = new DESKeySpec(encryptKey.getBytes()); SecretKey securekey = keyFactory.generateSecret(desKey); // Cipher对象实际完成加密操作 Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding"); // 偏移量 IvParameterSpec iv = new IvParameterSpec(encryptKey.getBytes()); // 用密匙初始化Cipher对象 cipher.init(Cipher.ENCRYPT_MODE, securekey, iv); // 执行加密操作 byte[] doFinal = cipher.doFinal(encryptString.getBytes()); return Base64Util.encode(doFinal); } catch (Exception e){ e.printStackTrace(); return null; } } /** * 功能描述:DES解密 方法。 * @param decryptString byte[]类型 要解密的数据(需要使用Base64将字符串转换成byte[]) * @param decryptKey String类型 解密时使用的KEY * @return String类型 解密后结果 */ public static byte[] decrypt(String decryptString, String decryptKey) { try { // 创建一个密匙工厂 SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); // 创建一个DESKeySpec对象 DESKeySpec desKey = new DESKeySpec(decryptKey.getBytes("UTF-8")); // 将DESKeySpec对象转换成SecretKey对象 SecretKey securekey = keyFactory.generateSecret(desKey); // Cipher对象实际完成解密操作 Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding"); // 偏移量 IvParameterSpec iv = new IvParameterSpec(decryptKey.getBytes("UTF-8")); // 用密匙初始化Cipher对象 cipher.init(Cipher.DECRYPT_MODE, securekey, iv); // 执行解密操作 return cipher.doFinal(decryptString.getBytes()); } catch (Exception e){ e.printStackTrace(); return null; } } /** * 功能描述:DES解密 方法。 * decryptBase64--->decrtpyDes * @param decryptString byte[]类型 要解密的数据(需要使用Base64将字符串转换成byte[]) * @param decryptKey String类型 解密时使用的KEY * @return String类型 解密后结果 */ public static String decryptBase64(String decryptString, String decryptKey) { try {// SecureRandom secureRandom = new SecureRandom(); byte[] decode = Base64Util.decode(decryptString); // 创建一个密匙工厂 SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); // 创建一个DESKeySpec对象 DESKeySpec desKey = new DESKeySpec(decryptKey.getBytes()); // 将DESKeySpec对象转换成SecretKey对象 SecretKey securekey = keyFactory.generateSecret(desKey); // Cipher对象实际完成解密操作 Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding"); // 偏移量 IvParameterSpec iv = new IvParameterSpec(decryptKey.getBytes()); // 用密匙初始化Cipher对象 cipher.init(Cipher.DECRYPT_MODE, securekey, iv); // 执行解密操作 byte[] doFinal = cipher.doFinal(decode); System.out.println(doFinal); return new String(doFinal); } catch (Exception e){ e.printStackTrace(); return null; } }}

测试如下:

@Test public void testDes(){ String key = "1020457f"; String src = "今天下雪了"; try { String encryptBase64 = DesUtil.encryptBase64(src, key); System.out.println("DesUtil 加密 : "+encryptBase64); String decryptBase64 = DesUtil.decryptBase64(encryptBase64, key); System.out.println("DesUtil 解密 : "+decryptBase64); } catch (Exception e) { e.printStackTrace(); } }

结果输出如下:

DesUtil 加密 : 7VhX51Twa8Z39WtXgJ3NWw== DesUtil 解密 : 今天下雪了


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:RSA - 非对称加密算法简要介绍与JAVA实现(rsa胎位)
下一篇:java synchronized的用法及原理详解
相关文章

 发表评论

暂时没有评论,来抢沙发吧~