DES算法

释放双眼,带上耳机,听听看~!

DES算法

  • 概要

  • DES是有IBM公司研制的一种对称加密算法,美国国家标准局于1977年公布把它作为非机要部门使用的数据加密标准。

    • DES是一个分组加密算法,就是将明文分组进行加密,每次按顺序取明文一部分,一个典型的DES以64位为分组,加密解密用算法相同。它的密钥长度为56位,因为每组第8位是用来做奇偶校验,密钥可以是任意56位的数,保密性依赖于密钥。

DES算法

  • 加密步骤

  • 首先生成一套加密密钥,我们提供一个64位的秘钥,然后通过等分、移位、选取、迭代形成一套16个加密密钥,分别供每一轮运算使用。

    • 假设目前取到一个64位分组,我们称之为M,M经过一个初始置换IP,置换成m0,。将m0明文分为左半部分和右半部分,各32位长。

    • 然后进行16轮完全相同的运算,在每一轮运算中数据与相应的秘钥结合。

    • 经过16轮之后,左、右半部分合在一起经过一个末置换(数据整理),这样就完成了加密过程。

DES算法

DES算法

  • 代码实现


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
1package Singleton;
2
3import javax.crypto.*;
4import javax.crypto.spec.SecretKeySpec;
5import java.security.InvalidKeyException;
6import java.security.Key;
7import java.security.NoSuchAlgorithmException;
8
9public class DESDemo {
10    public static void main(String[] args) {
11
12        /**
13         * 1.明文
14         * 2.提供原始秘钥 长度64位,8个字节
15         */
16        String clearText ="hello";
17        String originKey ="12345678";
18        try {
19            String cipherText = desEncrpt(clearText,originKey);
20            System.out.println(cipherText);
21        } catch (NoSuchPaddingException e) {
22            e.printStackTrace();
23        } catch (NoSuchAlgorithmException e) {
24            e.printStackTrace();
25        } catch (InvalidKeyException e) {
26            e.printStackTrace();
27        } catch (BadPaddingException e) {
28            e.printStackTrace();
29        } catch (IllegalBlockSizeException e) {
30            e.printStackTrace();
31        }
32    }
33
34    /**
35     * 用DES算法进行加密
36     * ciper
37     * @param clearText
38     * @param originKey
39     * 就是通过对比特为进行数学运算
40     * @return
41     */
42
43    private static String desEncrpt(String clearText, String originKey) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
44        //获取加密类对象
45        Cipher cipher =Cipher.getInstance("DES");
46        SecretKey key =getKey(originKey);
47        //对加密类对象进行初始化
48        //mode:加密/解密
49        //key:对原始秘钥处理之后的秘钥
50        cipher.init(Cipher.ENCRYPT_MODE,key);
51        //使用加密工具类对象对明文进行加密 变成密文
52       byte[] doFinal= cipher.doFinal(clearText.getBytes());//默认GBK进行编码
53        return new String(doFinal);//默认GBK解码 //如果之前使用了其他编码方式,传入后已之前为主。
54    }
55
56    private static SecretKey getKey(String originKey) {
57        SecretKeySpec key= new SecretKeySpec(originKey.getBytes(),"DES");
58        return key;
59    }
60}
61
62

1
2
1    * 上述代码会出现乱码问题,
2

1
2
3
1?茽%q%?
2
3

乱码出现的原因

DES算法

要找的编码表就是base64。

注:GBK、UTF-8、base64这些都是编码表

  • base64编码

  • 加密后的结果是字节数组,这些被加密后的字节在码表(如GBK、UTF-8码表)上找不到对应内容,会出现乱码。当乱码字符串再次转换为字节数组时,长度会变化,导致解密失败,所以转换后的数据是不安全的。

    • 使用Base64对字节数组进行编码,任何字节都能映射成对应的Base64字符,之后都能恢复到字节数组,利用数据的保存与传输,所以是安全的。

    • 改进后代吗


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
1import javax.crypto.*;
2import javax.crypto.spec.SecretKeySpec;
3import java.security.InvalidKeyException;
4import java.security.Key;
5import java.security.NoSuchAlgorithmException;
6
7public class DESDemo {
8    public static void main(String[] args) {
9
10        /**
11         * 1.明文
12         * 2.提供原始秘钥 长度64位,8个字节
13         */
14        String clearText ="hello";
15        String originKey ="12345678";
16        try {
17            String cipherText = desEncrpt(clearText,originKey);
18            System.out.println(cipherText);
19        } catch (NoSuchPaddingException e) {
20            e.printStackTrace();
21        } catch (NoSuchAlgorithmException e) {
22            e.printStackTrace();
23        } catch (InvalidKeyException e) {
24            e.printStackTrace();
25        } catch (BadPaddingException e) {
26            e.printStackTrace();
27        } catch (IllegalBlockSizeException e) {
28            e.printStackTrace();
29        }
30    }
31
32    /**
33     * 用DES算法进行加密
34     * ciper
35     * @param clearText
36     * @param originKey
37     * 就是通过对比特为进行数学运算
38     * @return
39     */
40
41    private static String desEncrpt(String clearText, String originKey) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
42        //获取加密类对象
43        Cipher cipher =Cipher.getInstance("DES");
44        SecretKey key =getKey(originKey);
45        //对加密类对象进行初始化
46        //mode:加密/解密
47        //key:对原始秘钥处理之后的秘钥
48        cipher.init(Cipher.ENCRYPT_MODE,key);
49        //使用加密工具类对象对明文进行加密 变成密文
50       byte[] doFinal= cipher.doFinal(clearText.getBytes());
51       byte[] encode =Base64.encode(doFinal);
52        return new String(encode);
53    }
54
55    private static SecretKey getKey(String originKey) {
56        SecretKeySpec key= new SecretKeySpec(originKey.getBytes(),"DES");
57        return key;
58    }
59}
60
61
  • 默认规定,给出的秘钥必须要有8个字节,64位,这样程序员每次必须要提供八个字符的字符串,如果超过或者不够,要报错。现在有需求,不论originKey多长,我们都要形成一个8个字节长度的原始秘钥,不够自动填,超过自动截取。


1
2
3
4
5
6
7
8
9
10
11
12
13
1    private static SecretKey getKey(String originKey) {
2        //不够 初始值为0
3        byte[]buffer =new byte[8];
4        //获取用户提供的原始密钥字节数组
5        byte[] originBytes =originKey.getBytes();
6        for(int i=0;i<8&&i<originBytes.length;i++){
7            buffer[i]=originBytes[i];
8        }
9        SecretKeySpec key= new SecretKeySpec(buffer,"DES");
10        return key;
11    }
12
13
  • 解密


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
1import javax.crypto.*;
2import javax.crypto.spec.SecretKeySpec;
3import java.security.InvalidKeyException;
4import java.security.Key;
5import java.security.NoSuchAlgorithmException;
6
7public class DesDemo {
8    public static void main(String[] args) {
9
10        /**
11         * 1.明文
12         * 2.提供原始秘钥 长度64位,8个字节
13         */
14        String clearText ="hello";
15        String originKey ="12345678";
16        try {
17            String cipherText = desEncrpt(clearText,originKey);
18            System.out.println(cipherText);
19            String clearText2 =desDecrpt(cipherText,originKey);
20            System.out.println(clearText2);
21        } catch (NoSuchPaddingException e) {
22            e.printStackTrace();
23        } catch (NoSuchAlgorithmException e) {
24            e.printStackTrace();
25        } catch (InvalidKeyException e) {
26            e.printStackTrace();
27        } catch (BadPaddingException e) {
28            e.printStackTrace();
29        } catch (IllegalBlockSizeException e) {
30            e.printStackTrace();
31        }
32    }
33
34    private static String desDecrpt(String cipherText, String originKey) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
35        //获取加密类对象
36        Cipher cipher =Cipher.getInstance("DES");
37        SecretKey key =getKey(originKey);
38        //对加密类对象进行初始化
39        //mode:加密/解密
40        //key:对原始秘钥处理之后的秘钥
41        cipher.init(Cipher.DECRYPT_MODE,key);
42        byte[] decodebytes =Base64.decode(cipherText);
43        //使用加密工具类对象对明文进行解密 变成明文
44        byte[] doFinal= cipher.doFinal(decodebytes);
45       // String encodetext =Base64.encode(doFinal);
46        return new String(doFinal);
47    }
48
49    /**
50     * 用DES算法进行加密
51     * ciper
52     * @param clearText
53     * @param originKey
54     * 就是通过对比特为进行数学运算
55     * @return
56     */
57
58    private static String desEncrpt(String clearText, String originKey) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
59        //获取加密类对象
60        Cipher cipher =Cipher.getInstance("DES");
61        SecretKey key =getKey(originKey);
62        //对加密类对象进行初始化
63        //mode:加密/解密
64        //key:对原始秘钥处理之后的秘钥
65        cipher.init(Cipher.ENCRYPT_MODE,key);
66        //使用加密工具类对象对明文进行加密 变成密文
67        byte[] doFinal= cipher.doFinal(clearText.getBytes());
68        String encodetext =Base64.encode(doFinal);
69        return new String(encodetext);
70    }
71
72    private static SecretKey getKey(String originKey) {
73        //不够 初始值为0
74        byte[]buffer =new byte[8];
75        //获取用户提供的原始密钥字节数组
76        byte[] originBytes =originKey.getBytes();
77        for(int i=0;i<8&&i<originBytes.length;i++){
78            buffer[i]=originBytes[i];
79        }
80        SecretKeySpec key= new SecretKeySpec(buffer,"DES");
81        return key;
82    }
83}
84
85
  • 思路:加密后的密文在GBK中有可能找不到,缺漏导致乱码,然后借助base64进行编码,在解密的时候,先通过base64解码,解码为GBK编码,最后结果返回。


1
2
3
1GBK->base64 ->base64->GBK
2
3

给TA打赏
共{{data.count}}人
人已打赏
安全经验

Google Adsense(Google网站联盟)广告申请指南

2021-10-11 16:36:11

安全经验

安全咨询服务

2022-1-12 14:11:49

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索