Des加密理解

DES全称为Data EncryptionStandard,即数据加密标准。Des加密算法是一种对称加密算法,所谓对称加密算法就是指对明文的加密以及对密文的解密用的是同一个密钥。

Des使用一个56位的密钥以及附加的8位奇偶校验位,产生最大64位的分组大小。这是一个迭代的分组密码,使用称为 Feistel 的技术,其中将加密的文本块分成两半。使用子密钥对其中一半应用循环功能,然后将输出与另一半进行“异或”运算;接着交换这两半,这一过程会继续下去,但最后一个循环不交换。DES 使用 16 个循环,使用异或,置换,代换,移位操作四种基本运算。

特点:数据加密标准,速度较快,适用于加密大量数据的场合。

Des算法的入口参数有三个:Key、Data、Mode。

  • Key: 为8个字节共64位,Des算法规定,其中第8、16、24、......64位是奇偶校验位,不参与Des运算,所以常说Des的密钥为56位。 在Des加密和解密的过程当中,密钥的长度都必须是8字节的倍数。

  • Data: 8个字节64位,是要被加密后解密的数据。

  • Mode: Des的工作方式:加密、解密。

Des加密模式

Des的加密模式主要有CBC模式,ECB模式,它们分别使用不同的加密方式加密。

ECB模式指的是电子密码本模式,是一种最古老,最简单的模式,将加密的数据分成若干组,每组的大小跟加密密钥长度相同;然后每组都用相同的密钥加密, 如果最后一个分组长度不够64位,要补齐64位。

ECB模式的特点是:

  1. 每次Key、明文、密文的长度都必须是64位;

  2. 数据块重复排序不需要检测;

  3. 相同的明文块(使用相同的密钥)产生相同的密文块,容易遭受字典攻击;

  4. 一个错误仅仅会对一个密文块产生影响;

CBC模式指的是加密块链模式,与ECB模式最大的不同是加入了初始向量。

CBC模式的特点是:

  1. 每次加密的密文长度为64位(8个字节);

  2. 当相同的明文使用相同的密钥和初始向量的时候CBC模式总是产生相同的密文;

  3. 密文块要依赖以前的操作结果,所以,密文块不能进行重新排列;

  4. 可以使用不同的初始化向量来避免相同的明文产生相同的密文,一定程度上抵抗字典攻击;

  5. 一个错误发生以后,当前和以后的密文都会被影响;

填充方式

常见的填充方式PKCS5Padding,PKCS5Padding表示当数据位数不足的时候要采用的数据补齐方式,也可以叫做数据填充方式。PKCS5Padding这种填充方式,具体来说就是“填充的数字代表所填字节的总数”

比如说,差两个字节,就是######22,差5个字节就是###55555,这样根据最后一个自己就可以知道填充的数字和数量。

保证加密解密的一致性 

在不同的平台上,只要能保证这几个参数的一致,就可以实现加密和解密的一致性。

  1. 加密和解密的密钥一致

  2. 采用CBC模式的时候,要保证初始向量一致

  3. 采用相同的填充模式


/**
* 加密

* @param data
* @param sKey
* @return
*/
public static byte[] encrypt(byte[] data, String sKey) {
try {
byte[] key = sKey.getBytes();
// 初始化向量
SecureRandom random = new SecureRandom();
DESKeySpec desKey = new DESKeySpec(key);
// 创建一个密匙工厂,然后用它把DESKeySpec转换成SecretKey
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
SecretKey securekey = keyFactory.generateSecret(desKey);
// Cipher对象实际完成加密操作
Cipher cipher = Cipher.getInstance("DES/ECB/NoPadding");
// 用密匙初始化Cipher对象
cipher.init(Cipher.ENCRYPT_MODE, securekey, random);
// 现在,获取数据并加密
// 正式执行加密操作
return cipher.doFinal(data);
} catch (Throwable e) {
e.printStackTrace();
}
return null;
}


/**
* 解密

* @param src
* @param sKey
* @return
* @throws Exception
*/
public static byte[] decrypt(byte[] src, String sKey) throws Exception {
byte[] key = sKey.getBytes();
// DES算法要求有一个可信任的随机数源
SecureRandom random = new SecureRandom();
// 创建一个DESKeySpec对象
DESKeySpec desKey = new DESKeySpec(key);
// 创建一个密匙工厂
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
// 将DESKeySpec对象转换成SecretKey对象
SecretKey securekey = keyFactory.generateSecret(desKey);
// Cipher对象实际完成解密操作
Cipher cipher = Cipher.getInstance("DES/ECB/NoPadding");
// 用密匙初始化Cipher对象
cipher.init(Cipher.DECRYPT_MODE, securekey, random);
// 真正开始解密操作
return cipher.doFinal(src);
}

猜你喜欢

转载自blog.csdn.net/witewater/article/details/78655284
今日推荐