密码学算法——DES密码算法 c++实现

本文详细介绍了DES密码算法的原理,包括混淆和扩散的概念,以及ECB和CBC两种加密模式。提供了DES算法的核心代码实现,包括密钥设置、加密和解密过程,同时解释了CBC模式中的异或操作。此外,文章还提到了DES算法在实际应用中的加密和解密流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

DES密码算法

1.算法原理

DES 设计中使用了分组密码设计的两个原则:混淆(confusion)和扩散(diffusion),其目的是抗击敌手对密码系统的统计分析。
混淆是使密文的统计特性与密钥的取值之间的关系尽可能复杂化,以使密钥和明文以及密文之间的依赖性对密码分析者来说是无法利用的。
扩散的作用就是将每一位明文的影响尽可能迅速地作用到较多的输出密文位中,以便在大量的密文中消除明文的统计结构,并且使每一位密钥的影响尽可能迅速地扩展到较多的密文位中, 以防对密钥进行逐段破译。

DES 密码的加解密算法基本流程如下图所示。
在这里插入图片描述

加密算法常见的有ECB模式和CBC模式:

  • ECB模式中,将数据按照8个字节一段进行DES加密或解密得到一段段的8个字节的密文或者明文,最后一段不足8个字节(一般补0或者F),按照需求补足8个字节进行计算(并行计算),之后按照顺序将计算所得的数据连在一起即可,各段数据之间互不影响。
  • CBC模式中,实现机制使加密的各段数据之间有了联系。其实现的机理如下:
  1. 首先将数据按照8个字节一组进行分组得到D1D2…Dn(若数据不是8的整数倍,用指定的PADDING数据补位,本实验中补0)
  2. 第一组数据D1与初始化向量Ⅳ异或后的结果进行DES加密得到第一组密文C
  3. 第二组数据D2与第一组的加密结果C1异或以后的结果进行DES加密,得到第二组密文C2
  4. 之后的数据以此类推,得到Cn
  5. 按顺序连为C1C2C3…Cn即为加密结果

比较CBC与ECB模式区别,如下图所示:
在这里插入图片描述

2.结果展示

在这里插入图片描述

本次算法没有使用MFC库,而是用Easy_X库手动画了一个,所以显得比较简陋,至于为什么呢,是因为我在汉字字符转换编码时用的GBK编码,做不了utf编码转换,而且我是用CLion写的,复制到VS时有些内容不兼容,所以干脆就用了Easy_X画了个界面出来。但作为DES算法核心的内容,应该也是通用的。

3.具体过程

本文主要是关于DES算法的具体实现过程,如果想要学习DES算法原理,推荐阅读DES加密算法这篇文章。

3.1核心代码DESCipher类

DESCipher.h

#include<iostream>
#include<sstream>
#include<cstring>
#include<iomanip>
#include<cmath>
#include<ctime>
#include<list>
#include<windows.h>
using namespace std;
class DESCipher{
   
   
private:
    string keys;//八字节密钥
    string keywords;//64位密钥
    string plains;//明文
    string plain_origin;//明文二进制
    string cipher;//密文
    string cipher_origin;//密文二进制
    string hex=("0123456789ABCDEF");
    string IV=("suixiang");
    string IV_origin;//初始化向量二进制
    char ckey[16][48];
    int IP[64] = {
   
           //IP置换表
            58, 50, 42, 34, 26, 18, 10, 2,
            60, 52, 44, 36, 28, 20, 12, 4,
            62, 54, 46, 38, 30, 22, 14, 6,
            64, 56, 48, 40, 32, 24, 16, 8,
            57, 49, 41, 33, 25, 17, 9, 1,
            59, 51, 43, 35, 27, 19, 11, 3,
            61, 53, 45, 37, 29, 21, 13, 5,
            63, 55, 47, 39, 31, 23, 15, 7
    };
    int NIP[64] = {
   
        //IP逆置换表
            40,  8, 48, 16, 56, 24, 64, 32,
            39,  7, 47, 15, 55, 23, 63, 31,
            38,  6, 46, 14, 54, 22, 62, 30,
            37,  5, 45, 13, 53, 21, 61, 29,
            36,  4, 44, 12, 52, 20, 60, 28,
            35,  3, 43, 11, 51, 19, 59, 27,
            34,  2, 42, 10, 50, 18, 58, 26,
            33,  1, 41,  9, 49, 17, 57, 25
    };
    int E[48] = {
   
               //扩展换位表
            32, 1, 2, 3, 4, 5,
            4, 5, 6, 7, 8, 9,
            8, 9, 10, 11, 12, 13,
            12, 13, 14, 15, 16, 17,
            16, 17, 18, 19, 20, 21,
            20, 21, 22, 23, 24, 25,
            24, 25, 26, 27, 28, 29,
            28, 29, 30, 31, 32, 1
    };
    int PC1[56] = {
   
              //PC1换位表(64—>56)
            57, 49, 41, 33, 25, 17, 9,
            1, 58, 50, 42, 34, 26, 18,
            10, 2, 59, 51, 43, 35, 27,
            19, 11, 3, 60, 52, 44, 36,
            63, 55, 47, 39, 31, 23, 15,
            7, 62, 54, 46, 38, 30, 22,
            14, 6, 61, 53, 45, 37, 29,
            21, 13, 5, 28, 20, 12, 4
    };
    int move[16] = {
   
             //循环移位表
            1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1
    };
    int PC2[48] = {
   
              //PC2换位表(56—>48)
            14, 17, 11, 24, 1, 5,
            3, 28, 15, 6, 21, 10,
            23, 19, 12, 4, 26, 8,
            16, 7, 27, 20, 13, 2,
            41, 52, 31, 37, 47, 55,
            30, 40, 51, 45, 33, 48,
            44, 49, 39, 56, 34, 53,
            46, 42, 50, 36, 29, 32
    };
    int S[8][4][16] = {
   
   
            {
   
   		{
   
   14,4,13,1,2,15,11,8,3,10,6,12,5,9,0,7},
                    {
   
   0,15,7,4,14,2,13,1,10,6,12,11,9,5,3,8},
                    {
   
   4,1,14,8,13,6,2,11,15,12,9,7,3,10,5,0},
                    {
   
   15,12,8,2,4,9,1,7,5,11,3,14,10,0,6,13}
            },//S1
            {
   
   		{
   
   15,1,8,14,6,11,3,4,9,7,2,13,12,0,5,10},
                    {
   
   3,13,4,7,15,2,8,14,12,0,1,10,6,9,11,5},
                    {
   
   0,14,7,11,10,4,13,1,5,8,12,6,9,3,2,15},
                    {
   
   13,8,10,<
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值