DES

DES 算法简介

DES 加密算法属于对称密码范畴,那么什么是对称密码呢?加密和解密过程中所使用的密钥相同,就是对称密码,而且大多数对称密码算法,加密解密过程都是互逆的。DES 算法是一种数据加密算法,明文按照 64 位进行分组,分组后的明文与密钥按位替代或交换的方法形成密文组。 密钥的长度是 64 位(其实是56位,其中有8位是奇偶校验位)。

DES 工作模式简介

1 . ECB(电子密码密码本模式)

这是最原始的一种加密工作模式,将明文分组成64位,与密钥长度相同,然后按照加密算法加密,得到 64位密文,最后将所有加密后的密文连接在一起即可,各段之间互不影响(当最后一段不足64位是要补足64位在进行计算)

可见,这种模式的优点是实现起来简单,有利于并行运算,但是缺点是安全性比较低。

2 . CBC (密文链接模式)

这种模式相比于 ECB 就比较复杂了,让我们来看看它是如何加密的

    1. 首先将数据按照8个字节一组进行分组得到D1D2......Dn(若数据不是8的整数倍,用指定的PADDING数据补位)
    2. 第一组数据D1与初始化向量I异或后的结果进行DES加密得到第一组密文C1(初始化向量I为全零)
    3. 第二组数据D2与第一组的加密结果C1异或以后的结果进行DES加密,得到第二组密文C2
    4. 之后的数据以此类推,得到Cn
    5. 按顺序连为C1C2C3......Cn即为加密结果。

这种加密模式相比于上一中比较安全一些,但是有一个致命的缺点,就是误差延续性,就是说只要有一个地方的密文出现错误,那么底下的密文就都会出现错误,为什么会这样?仔细看看加密过程就能明白,这也就是为什么这种模式叫做链接模式。

当然还有其他的模式,就不一一介绍了,一般还是利用以上两种模式。

DES 填充模式

  NoPadding    
  API或算法本身不对数据进行处理,加密数据由加密双方约定填补算法。例如若对字符串数据进行加解密,可以补充\0或者空格,然后trim。

   PKCS5Padding   
   加密前:数据字节长度对8取余,余数为m,若m>0,则补足8-m个字节,字节数值为8-m,即差几个字节就补几个字节,字节数值即为补充的字节数,若为0则补充8个字节的8

填充模式就用于当明文不是64的倍数的时候,由于在加密的过程中需要对明文进行分块,所以需要选择填充模式。

DES 的使用

1 . 和 Hmac 算法一样,想要使用 DES,首先要获取密钥,这需要借助于 JDK 自带的 KeyGenerator

public static byte[] initKey() throws Exception {
    KeyGenerator keyGenerator = KeyGenerator.getInstance("DES");
    keyGenerator.init(56); // 56 可填可不填

    SecretKey secretKey = keyGenerator.generateKey();
    return secretKey.getEncoded();
}

2 . 接下来就是 DES 加密过程

public static byte[] encryptDES(byte[] key, byte[] data) throws Exception {

        SecretKey secretKey = new SecretKeySpec(key, "DES");

        Cipher cipher = Cipher.getInstance("DES");
        cipher.init(Cipher.ENCRYPT_MODE, secretKey);
        byte[] resultBytes = cipher.doFinal(data);
        return resultBytes;

    }

传进去一个 helloworld 看看结果

public static void main(String[] args) throws Exception {
        String data = "helloworld";
        byte[] key = initKey();

        byte[] resultBytes = encryptDES(key, data.getBytes());

        String resultString = byteToHexString(resultBytes);

        System.out.println(resultString);

    }

结果为

215f9748bf31d5dc3d4eb5b77107643b

既然 DES 是用于数据加密,那么我们总应该能把数据还原成明文把,不然其意义何在呢?其实解密过程和加密过程几乎一模一样,如下所示

public static String decryptDES(byte[] key, byte[] data) throws Exception {
        SecretKey secretKey = new SecretKeySpec(key, "DES");

        Cipher cipher = Cipher.getInstance("DES");
        cipher.init(Cipher.DECRYPT_MODE, secretKey);

        byte[] resultBytes = cipher.doFinal(data);

        return new String(resultBytes);
    }

这个时候传进来的 key 必须和加密时使用的 key 是相同的,而且这个时候传进来的 data 也必须是加密过后的密文。

咦,这个时候我们发现,我们开头介绍的加密模式和填充模式好像都没用到,其实我们一般是使用默认就可以了,如果有特殊需要,可以这样使用

Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");

DES加密过后的数据在以前是不可能被破解的,但是由于计算机的发展,DES 加密过得数据在如今完全可在24小时内被破解,所以在 DES 的基础上有延伸出了 3DES 和 AES,这两种算法将留到以后再介绍~

你可能感兴趣的:(DES)