懂了!国际算法体系对称算法DES原理

简介: 懂了!国际算法体系对称算法DES原理

概念


加密领域主要有国际算法和国密算法两种体系。国密算法是国家密码局认定的国产密码算法。国际算法是由美国安全局发布的算法。由于国密算法安全性高等一系列原因。国内的银行和支付机构都推荐使用国密算法。


1112728-20201114172550037-773800474.png


从上图可知,对称加密算法在算法体系里占了半壁江山。因为国际和国密算法的过程差异并不大。只是应用的数学公式和秘钥位数不同。DES在里面算是基础,所以今天主要介绍一下DES的原理。

 

原理


密码


咱们从加密的原理说起。举个最简单的加密:


我有一段明文:520


我的秘钥是:221


我的加密算法是:加法


加密后的密文就是:741


如果这个密文被截获了,接受者看到的信息是:741(气死你),和原来明文520是完全不同的,不能知道信息原有的意思。

 

从这个简单的例子可知:加密是包含:明文、秘钥、加密算法和密文四个要素的。加密算法可公开可不公开,常见的算法有:位移、循环位移、异或、置换、数学函数。

 

凯撒密码


加密技术从古罗马凯撒时候就在用:凯撒密码


1112728-20201114172611756-346340837.png


凯撒密码是古罗马时期凯撒大帝和他的将军们通信时使用的加密方式:


明文:由26个字母组成


秘钥:1到25之间的任意数字


加密算法:循环位移


密文:举例明文为eat 秘钥为2,对照上面图片的凯撒密码盘可以得到密文是gcv。

 

@Test
public void caesarCipher() {
    String text = "love was growing in eyes";  //明文
        int key = 3; //秘钥
        String cipher = encryptCaesarCipher(text, key); //密文
        System.out.println(cipher);
}
//凯撒密码加密算法
private String encryptCaesarCipher(String text, int key) {
    char[] chars = text.toCharArray();
    for(int i=0; i<chars.length; i++) {
        if(chars[i] != ' ') {
            chars[i] = (char)(chars[i]+key);
        }
        //如果超过了26个字母,则减去26
        if(chars[i]>122) {
            chars[i] = (char)(chars[i]-26);
        }
    }
    return new String(chars);
}


运行得到密文:oryh zdv jurzlqj lq hbhv

 

凯撒密码连小朋友都能破解。一旦被人知道用的凯撒密码,算法是已知的。要破解秘钥拿个明文和密文试试就知道了。就是平时说的暴力破解法可以很容易破解。对于这种全是英文字符的也可以使用频率分析法。频率分析法可以理解为基于大数据的方法,因为26个字母中,e的使用频率高。如果比如一篇文章,单词足够多的话,出现频率最高的字母xxx就是e。xxx的char值e的char值就是秘钥了。


1112728-20201114172630185-2086585316.png


DES


概述


DES全称为Data Encryption Standard,即数据加密标准,是一种分组加密算法。其分组长度为64bit,密钥长度为64bit,其中8bit为校验位,所以实际长度为56bit。

 

先介绍一下校验位。举个例子,咱们的身份证号码都是18位。这18位包含:


1112728-20201114172656130-1910231144.png


其中最后一位就是校验位,原理是利用将前面部分利用某种算法计算得到一个数。如果校验位与算法得到的不一致,则数据是有问题的。所以身份证本身是有不通过查库就可以简单验证有效性功能的。

 

回到DES算法。DES算法的秘钥必须是64位,参与加密计算的是56位。这是原始秘钥。这个原始秘钥会用一个函数转换成16个64位秘钥。

 

加密过程


DES的加密过程:


明文64位->初始IP置换->16轮加密变换->逆初始IP置换->密文

 

DES算法的这个过程又被称为Feistel网络。

 

 

简单解释下:


明文我们自己想写多长写多长。但是加密的时候每次以64bit作为一个分组。最后将密文拼接起来。



1112728-20201114172728076-285995472.png


然后执行一个IP置换(初始置换)操作。IP置换就是按位置换。举例来说64bit就是64个0和1。把第40个位置上的数换成第50个位置上的数就是置换了。


置换好的64个bit会分成两个32bit。然后用相同的加密算法每次传不同的转换后秘钥做16轮。


然后将两组32bit拼接起来再进行一次IP置换(终结置换)变成密文

 

分组组合


刚才介绍的加密过程是把明文的一块怎么加密成密文。DES密码块与密码块连接方式遵循对称加密的方式。


对称加密有两种方式,一种是分组加密,一种是序列加密。


分组加密,也叫块加密(block cyphers),一次加密明文中的一个块。是将明文按一定的位长分组,明文组经过加密运算得到密文组,密文组经过解密运算(加密运算的逆运算),还原成明文组。


序列加密,也叫流加密(stream cyphers),一次加密明文中的一个位。是指利用少量的密钥通过某种复杂的运算(密码算法)产生大量的伪随机位流,用于对明文位流的加密。

 

分组加密算法中,分组密码的设计基本遵循混淆原则和扩散原则。有ECB,CBC,CFB,OFB这4种算法模式。DES有ECB和CBC两种实现。

 

ECB模式


ECB模式就是每组明文分别加密后拼接起来。


1112728-20201114172815742-1482557325.png


CBC模式


CBC即密码分组链接(Cipher-block chaining)的简称。在CBC模式中,每个明文块先与前一个密文块进行异或后,再进行加密。在这种方法中,每个密文块都依赖于它前面的所有明文块。同时,为了保证每条消息的唯一性,在第一个块中需要使用初始化向量。在DES中,初始化向量就是秘钥。


1112728-20201114172845796-787158266.png


程序实现


我们用程序来实现一下DES加密算法


@Test
public void desCiper() throws Exception{
    String key = "12345678";
    String text = "我知道我是任性很任性,伤透了你的心";  //明文
        String cipher = encryptDesCipher(text, key); //密文
        System.out.println(cipher);
    text = decryptDesCipher(cipher, key);  //明文
         System.out.println(text);
}
//DES加密算法
private String encryptDesCipher(String text, String origKey) throws Exception{
    Key key = new SecretKeySpec(origKey.getBytes(), "DES");
    Cipher cipher = Cipher.getInstance("DES");
    cipher.init(Cipher.ENCRYPT_MODE, key);
    return Base64.encode(cipher.doFinal(text.getBytes()));
}
//DES加密算法
private String decryptDesCipher(String text, String origKey) throws Exception{
    Key key = new SecretKeySpec(origKey.getBytes(), "DES");
    Cipher cipher = Cipher.getInstance("DES");
    cipher.init(Cipher.DECRYPT_MODE, key);
    return new String(cipher.doFinal(Base64.decode(text)));
}


运行结果:


xo6mmVe8j1/d60cAAiFz1HAXxihi2FH5d0zMWILvEYISWR52lguy2TbMZQ4vuulCdO8WvxMRuXE=


我知道我是任性很任性,伤透了你的心

 

3DES


3DES即3重加密算法,是对每个数据块应用三次DES算法。这是为了应对计算机计算能力增强,DES变的容易破解而产生的。


主要方法就是DES秘钥64位,3DES秘钥64*3=192位,分成个三个秘钥,进行2轮DES加密,1轮DES解密。最终得到结果。


1112728-20201114172910468-51418578.png


AES


AES全称是高级加密标准(Advanced Encryption Standard)。是用来替代DES/3DES的。主要过程如下,这里不过多介绍。


1112728-20201114172930255-1435801875.png


应用


我们来回顾下https的SSL握手过程:


1112728-20201114172950167-1225782775.png


SSL握手的最后,双方会用非对称秘钥协商出一个对称秘钥。用对称秘钥来加密传输的数据。之所以这样做是因为非对称加密安全性高但是效率低,对称秘钥正好相反。对称秘钥可以被暴力破解,破解需要时间。如果破解出来时就过期了,再通信就用另外的秘钥就能保证信息安全。

 

我们来模拟一下已经协商好的秘钥之后http客户端与服务器端的通信。


@Test
public void client() throws Exception {
    int i = 1;
    while (i <= 2) {
        Socket socket = new Socket("127.0.0.1", 520);
        //向服务器端第一次发送字符串
        OutputStream netOut = socket.getOutputStream();
        InputStream io = socket.getInputStream();
        String msg = i == 1 ? "客户端:我知道我是任性太任性,伤透了你的心。我是追梦的人,追一生的缘分。":
        "客户端:我愿意嫁给你,你却不能答应我。";
        System.out.println(msg);
        netOut.write(encryptDesCipher(msg.getBytes(), "12345678"));
        netOut.flush();
        byte[] bytes = new byte[i==1?104:64];
        io.read(bytes);
        String response = new String(decryptDesCipher(bytes,"12345678"));
        System.out.println(response);
        netOut.close();
        io.close();
        socket.close();
        i++;
    }
}
@Test
public void server() throws Exception {
    ServerSocket serverSocket = new ServerSocket(520);
    int i = 1;
    while (i <= 2) {
        String msg = i == 1 ? "服务端:我知道你是任性太任性,伤透了我的心。同是追梦的人,难舍难分。" :
                "服务端:你愿意嫁给我,我却不能向你承诺。";
        Socket socket = serverSocket.accept();
        InputStream io = socket.getInputStream();
        byte[] bytes = new byte[i==1?112:64];
        io.read(bytes);
        System.out.println(new String(decryptDesCipher(bytes,"12345678")));
        OutputStream os = socket.getOutputStream();
        System.out.println(msg);
        byte[] outBytes = encryptDesCipher(msg.getBytes(), "12345678");
        os.write(outBytes);
        os.flush();
        os.close();
        io.close();
        i++;
    }
}


//DES加密算法
private byte[] encryptDesCipher(byte[] text, String origKey) throws Exception {
    Key key = new SecretKeySpec(origKey.getBytes(), "DES");
    Cipher cipher = Cipher.getInstance("DES");
    cipher.init(Cipher.ENCRYPT_MODE, key);
    return cipher.doFinal(text);
}
//DES加密算法
private byte[] decryptDesCipher(byte[] text, String origKey) throws Exception {
    Key key = new SecretKeySpec(origKey.getBytes(), "DES");
    Cipher cipher = Cipher.getInstance("DES");
    cipher.init(Cipher.DECRYPT_MODE, key);
    return cipher.doFinal(text);
}


运行结果


客户端:我知道我是任性太任性,伤透了你的心。我是追梦的人,追一生的缘分。


服务端:我知道你是任性太任性,伤透了我的心。同是追梦的人,难舍难分。


客户端:我愿意嫁给你,你却不能答应我。


服务端:你愿意嫁给我,我却不能向你承诺。

 

这个程序实现了简单的客户端和服务器端的DES加密方式通信。稍加改造可以实现一个信息加密的聊天小程序。

 

总结


本文使用概念、原理、应用的传统型逻辑架构来对DES做系统梳理。里面涉及到的一些基本知识限于篇幅省略了一些。


比如Base64编码。它是加密时常用的编码方式,我们平时所看到的密钥都是base64后的结果。可以简单理解为对2的6次方进行64进制运算,可防止乱码丢失字节。


再比如填充字节这部分也没有介绍,有兴趣可以自己查阅下。

 

加解密很多人工作中或多或少都有涉及。我个人认为只要涉及的地方至少要了解到原理和架构层面,才能避免遇到问题时【拿着锤子找钉子】找不到真正问题的窘境。而只有动手实践才能避免当时了解了,过后又忘了需要再看一遍而产生重复工作的问题。

相关文章
|
27天前
|
机器学习/深度学习 存储 算法
神经网络分类算法原理详解
神经网络分类算法原理详解
49 0
|
1月前
|
算法
经典控制算法——PID算法原理分析及优化
这篇文章介绍了PID控制算法,这是一种广泛应用的控制策略,具有简单、鲁棒性强的特点。PID通过比例、积分和微分三个部分调整控制量,以减少系统误差。文章提到了在大学智能汽车竞赛中的应用,并详细解释了PID的基本原理和数学表达式。接着,讨论了数字PID的实现,包括位置式、增量式和步进式,以及它们各自的优缺点。最后,文章介绍了PID的优化方法,如积分饱和处理和微分项优化,以及串级PID在电机控制中的应用。整个内容旨在帮助读者理解PID控制的原理和实际运用。
88 1
|
1月前
|
算法 安全 C语言
使用C语言实现DES算法代码
使用C语言实现DES算法代码
|
1月前
|
机器学习/深度学习 算法 数据可视化
探索线性回归算法:从原理到实践
探索线性回归算法:从原理到实践【2月更文挑战第19天】
21 0
探索线性回归算法:从原理到实践
|
2月前
|
存储 算法 数据库
C++ “雪花算法“原理
C++ “雪花算法“原理
|
14天前
|
机器学习/深度学习 自然语言处理 算法
|
3天前
|
数据可视化 算法
【视频】Copula算法原理和R语言股市收益率相依性可视化分析-1
【视频】Copula算法原理和R语言股市收益率相依性可视化分析
16 0
|
22天前
|
存储 算法 编译器
【数据结构】栈算法(算法原理+源码)
【数据结构】栈算法(算法原理+源码)
【数据结构】栈算法(算法原理+源码)
|
27天前
|
缓存 算法 关系型数据库
深度思考:雪花算法snowflake分布式id生成原理详解
雪花算法snowflake是一种优秀的分布式ID生成方案,其优点突出:它能生成全局唯一且递增的ID,确保了数据的一致性和准确性;同时,该算法灵活性强,可自定义各部分bit位,满足不同业务场景的需求;此外,雪花算法生成ID的速度快,效率高,能有效应对高并发场景,是分布式系统中不可或缺的组件。
深度思考:雪花算法snowflake分布式id生成原理详解
|
1月前
|
算法
PID算法原理分析及优化
这篇文章介绍了PID控制方法,一种广泛应用于机电、冶金等行业的经典控制算法。PID通过比例、积分、微分三个部分调整控制量,以适应系统偏差。文章讨论了比例调节对系统响应的直接影响,积分调节如何消除稳态误差,以及微分调节如何减少超调。还提到了数字PID的实现,包括位置式、增量式和步进式,并探讨了积分饱和和微分项的优化策略。最后,文章简述了串级PID在电机控制中的应用,并强调了PID控制的灵活性和实用性。
39 1