精华内容
下载资源
问答
  • des加密算法c语言版)
    2021-05-25 07:45:08

    ![这里写图片描述][70]

    ![这里写图片描述][70 1]

    ![这里写图片描述][70 2]

    ## main.cpp ##

    #include

    #include

    #include"tables.h" //数据表

    //置换函数

    //参数: In:待置换数据指针

    //Out:置换输出指针

    // n:置换表长度

    //P:置换表指针

    //说明:将输入数据的指定位置作为输出数据的第i位。指定位置即置换表第i位的十进制数。得到的输出数据的长度

    //即为置换表的长度。

    void myPermutation(char *In,char *Out,int n,char *P)

    {

    int i=0;

    for(i=0; i

    *(Out+i)=*(In+*(P+i)-1);

    *(Out+i)='\0';

    }

    //按位异或函数

    //参数:In1:二进制串1

    //In2:二进制串2

    //n:二进制串长度

    // Out:异或结果

    //说明:循环比较两个二进制串每一位,不同则为'1',相同则为'0'

    void myXOR(char* In1,char* In2,int n,char* Out)

    {

    int i=0;

    for(i=0; i

    *(In1+i)!=*(In2+i) ? *(Out+i)='1' : *(Out+i)='0';

    }

    //循环左移函数

    //参数: In:待移位二进制串

    // Out:移位后二进制串

    //n:二进制串长度

    //s:循环位数

    //说明:将输入二进制串移位后对应位置的值赋给输出串,为保证循环(即原二进制串的第一位变成移位后的

    //最后一位),将位次相加后与串的长度做模运算。

    void myShift(char *In,char *Out,int n,int s)

    {

    int i=0;

    for(i=0; i

    *(Out+i)=*(In+(s+i)%n);

    *(Out+i)='\0';

    }

    //生成子密钥函数

    //参数: K:64位的密钥

    //(*SK)[49]:得到的一轮子密钥

    //说明:输入64位密钥,进行置换选择1,之后进行16轮操作得到16个子密钥,每一轮对56位分成两部分,

    //进行相应位数的移位操作,之后再拼接成56位进行置换选择2,得到该轮子密钥

    void mySubkey(char* K,char (*SK)[49])

    {

    char out[57],C[57],D[29],e[29],t[57];

    int i=0,j=0;

    myPermutation(K,out,56,*PC_1); //置换选择1

    strcpy(C,out); //C0

    strcpy(D,out+28); //D0

    for(j=0; j<16; j++)

    {

    myShift(C,e,28,move_time[j]); //循环左移

    strcpy(C,e); //Cj

    myShift(D,e,28,move_time[j]);

    strcpy(D,e); //Dj

    strncpy(t, C, 28);

    strncpy(t+28, D, 28);

    myPermutation(t,*(SK+j),48,*PC_2);//置换选择2,得到Kj

    }

    }

    //轮函数f

    //参数: L: 第t轮的32位L

    //R: 第t轮的32位R

    //SK: 第t轮的48位子密钥

    //t: 轮数

    //说明:共进行16轮操作,每轮的32位R先进行拓展置换E变成48位,再与该轮子密钥异或,然后分成

    //8组进行S盒代换。每组通过第1,6位组成的二进制串确定S盒行号,通过第2,3,4,5位确定列号,

    //找到对应的数并转为4位二进制串。8组代换拼接成32位为S盒代换结果,然后进行置换P。每轮经过

    //S盒代换得到的结果与上一轮的L异或作为本轮的R,上一轮的R作为本轮的L。

    void myf(char* L,char* R,char* SK,int t)

    {

    int i=0,j=0;

    int row,col;

    char out1[49]= { 0},out2[49]= { 0},out3[33]= { 0},out4[33]= { 0},temp[33]= { 0};

    printf("K%d=",t+1);

    puts(SK);

    myPermutation(R,out1,48,*E); //扩展置换E

    printf("E(R%d)=",t);

    puts(out1);

    myXOR(out1,SK,48,out2); //与子密钥异或

    printf("E(R%d)^K%d=",t,t+1);

    puts(out2);

    for(i=0; i<8; i++) //S盒代换

    {

    row = ((out2[i*6]-'0')<<1)+(out2[i*6+5]-'0'); //第1,6位组成行号

    col = ((out2[i*6+1]-'0')<<3)+((out2[i*6+2]-'0')<<2)+((out2[i*6+3]-'0')<<1)

    +(out2[i*6+4]-'0'); //第2,3,4,5位组成列号

    for(j=3; j>=0; j--)

    *(out3+(i*4+3-j))=((S_Box[i][row*16+col]>>j)&1)+'0'; //将取到的S盒数据填到S盒输出的指定位置,先进行十进制转二进制

    }

    *(out3+32)='\0';

    printf("%d轮S盒输出=",t+1);

    puts(out3);

    myPermutation(out3,out4,32,*P); //置换P

    printf("f(R%d,K%d)=",t,t+1);

    puts(out4);

    strcpy(temp,R); //保存旧的R

    myXOR(L,out4,32,R); //更新R

    printf("R%d=",t+1);

    puts(R);

    strcpy(L,temp); //更新L

    }

    //主函数:

    //说明:输入64位明文,先进行初始置换IP操作,接下来将置换输出的 64 位数据分成左右两半,左一半称为 L0 ,

    //右一半称为 R0 ,各 32 位。然后进行16轮迭代,迭代过程我和轮函数写在了一起。迭代完成后再经逆IP置换得到密文。

    int main()

    {

    char* M="0000000100100011010001010110011110001001101010111100110111101111";

    char* K="0001001100110100010101110111100110011011101111001101111111110001";

    char out[65],L[33],R[33],SK[16][49],cipher[65];

    int i=0;

    mySubkey(K,SK); //产生16轮子密钥

    myPermutation(M,out,64,*IP); //初始置换IP

    printf("IP置换:");

    puts(out);

    strcpy(L,out); //L0

    strcpy(R,out+32); //R0

    for(i=0; i<16; i++)

    {

    printf("\n-------------------------------第%d轮------------------------------------\n"

    ,i+1);

    myf(L,R,*(SK+i),i);

    }

    strncpy(out, R, 32); //L16 + R16

    strncpy(out+32, L, 32);

    myPermutation(out,cipher,64,*C_IP); //逆IP置换

    printf("\n密文:");

    puts(cipher);

    return 0;

    }

    \#\#数据表tables.h

    //选择置换PC-1

    char PC_1[8][7]=

    {

    { 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}

    };

    //选择置换PC-2

    char PC_2[8][6]=

    {

    { 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}

    };

    //IP置换

    char IP[8][8]=

    {

    { 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}

    };

    //逆IP置换

    char C_IP[8][8]=

    {

    { 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}

    };

    //扩展置换E

    char E[8][6]=

    {

    { 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}

    };

    //扩展置换P

    char P[4][8]=

    {

    { 16,7,20,21,29,12,28,17},

    { 1,15,23,26,5,18,31,10},

    { 2,8,24,14,32,27,3,9},

    { 19,13,30,6,22,11,4,25}

    };

    //S盒

    char S_Box[8][65]=

    {

    {

    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

    },

    {

    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,1,3,15,4,2,11,6,7,12,10,5,14,9

    },

    {

    10,0,9,14,6,3,15,5,1,13,12,7,11,4,2,8,

    13,7,0,9,3,4,6,10,2,8,5,14,12,11,15,1,

    13,6,4,9,8,15,3,0,11,1,2,12,5,10,14,7,

    1,10,13,0,6,9,8,7,4,15,14,3,11,5,2,12

    },

    {

    7,13,14,3,0,6,9,10,1,2,8,5,11,12,4,15,

    13,8,11,5,6,15,0,3,4,7,2,12,1,10,14,9,

    10,6,9,0,12,11,7,13,15,1,3,14,5,2,8,4,

    3,15,0,6,10,1,13,8,9,4,5,11,12,7,2,14

    },

    {

    2,12,4,1,7,10,11,6,8,5,3,15,13,0,14,9,

    14,11,2,12,4,7,13,1,5,0,15,10,3,9,8,6,

    4,2,1,11,10,13,7,8,15,9,12,5,6,3,0,14,

    11,8,12,7,1,14,2,13,6,15,0,9,10,4,5,3

    },

    {

    12,1,10,15,9,2,6,8,0,13,3,4,14,7,5,11,

    10,15,4,2,7,12,9,5,6,1,13,14,0,11,3,8,

    9,14,15,5,2,8,12,3,7,0,4,10,1,13,11,6,

    4,3,2,12,9,5,15,10,11,14,1,7,6,0,8,13

    },

    {

    4,11,2,14,15,0,8,13,3,12,9,7,5,10,6,1,

    13,0,11,7,4,9,1,10,14,3,5,12,2,15,8,6,

    1,4,11,13,12,3,7,14,10,15,6,8,0,5,9,2,

    6,11,13,8,1,4,10,7,9,5,0,15,14,2,3,12

    },

    {

    13,2,8,4,6,15,11,1,10,9,3,14,5,0,12,7,

    1,15,13,8,10,3,7,4,12,5,6,11,0,14,9,2,

    7,11,4,1,9,12,14,2,0,6,10,13,15,3,5,8,

    2,1,14,7,4,10,8,13,15,12,9,0,3,5,6,11

    }

    };

    //左移位数

    int move_time[16] = { 1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1};

    \#\#\#\#运行结果:

    ![这里写图片描述][70 3]

    ![这里写图片描述][70 4]

    ![这里写图片描述][70 5]

    [70]: /images/20210502/7a8a7c16ffa54069823a4079b7f90fc4.png

    [70 1]: /images/20210502/ea719ed18d154c9a95b46e4d9ed5af27.png

    [70 2]: /images/20210502/5be2cd763bda4171bc91ab67457c2f98.png

    [70 3]: /images/20210502/1028314ba5514f5d9e0f18444a1b6314.png

    [70 4]: /images/20210502/069684257d5c4f1b8a36b6cb4c72801b.png

    [70 5]: /images/20210502/bc72f28319924d179be453d55eaa7b07.png

    更多相关内容
  • DES,DES加密算法,DES算法源码。用C写的DES加密算法。 DES,DES加密算法,DES算法源码。 DES加密算法(c语言实现) (本程序可以直接使用)
  • DES-加密解密语言算法C语言实现文档带有完整的源代码,可加密字符串或者文件,已通过测试使用。
  • DES的英文全称是Data Encryption Standard,意思是数据加密标准。而我们本篇文章讨论的是DES的加密算法。...DES算法是一种典型的分组密码,即将固定长度的明文通过一系列复杂的操作变成同样长度密文的算法。
  • DES加密算法其实分为两个部分,一部分对密钥进行处理 ,一部分对明文进行处理。 下面从一个例子说明: 64位明文: M=00110000 00110001 00110010 00110011 00110100 00110101 00110110 00110111 64位密钥: K=...

    加密

    DES加密算法其实分为两个部分,一部分对密钥进行处理 ,一部分对明文进行处理。
    下面从一个例子说明:
    64位明文:

    M=00110000 00110001 00110010 00110011 00110100 00110101 00110110 00110111
    

    64位密钥:

    K=00110001 00110010 00110011 00110100 00110101 00110110 00110111 00111000
    

    密钥

    K=00110001 00110010 00110011 00110100 00110101 00110110 00110111 00111000

    置换选择

    置换选择1(PC_1)8*7矩阵:

    int pc_1[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
        };
    

    在密钥当中,前八位00110001,第8位的1是奇偶校验位
    这个表有两个作用,一是去掉8个奇偶校验位,二是其他位打乱重排,即得到的56位密钥(64-8)中第1位的数是原来64位的第57位的数,第2位的数是原来的第49位的数。。。
    其实不用特意去掉奇偶校验位,因为按PC_1换位置之后剩下来的8位就是奇偶校验位,直接舍去就可以。

    经过上面的变换我们就可以得到56位的密钥:

    K(56)=0000000 0000000 0011111 1111111 0110011 0011110 001000 00001111
    

    再将前28位存储到C0,后28位存储到D0,即:

    C0(28)=0000000 0000000 0011111 1111111
    D0(28)=0110011 0011110 001000 00001111
    

    循环左移

    为了得到16个子密钥,我们需要有16对C和D。
    C1为C0循环左移得到,D1为D0循环左移得到,C2为C1循环左移得到,D2为D1循环左移得到、、、
    循环左移的位数如图所示:
    在这里插入图片描述
    循环左移1位的意思是把第一位保留下来,其他位左移,再将保留的第一位填到最后空出来的1位。
    可以得到结果:
    第一轮:

    C1=0000000 0000000 0111111 1111110
    D1=1100110 0111100 0100000 0011110
    

    第二轮:

    C2=0000000 0000000 1111111 1111100
    D2=1001100 1111000 1000000 0111101
    


    第16轮:

    C16=0000000 0000000 0011111 1111111
    D16=0110011 0011110 0010000 0001111
    

    左移完成后,将每对拼接起来构成56位的密钥

    K1(56)=0000000 0000000 0111111 1111110 1100110 0111100 0100000 0011110
    

    接下来进行第二次置换
    置换选择2(PC_2)6*8矩阵:

    int pc_2[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
        };
    

    将56位变为48位,和PC_1原理一样,最终得到16个子密钥:

    k1(48)=010100000010110010101100010101110010101011000010
    k2(48)=010100001010110010100100010100001010001101000111
    k3(48)=110100001010110000100110111101101000010010001100
    k4(48)=111000001010011000100110010010000011011111001011
    k5(48)=111000001001011000100110001111101111000000101001
    k6(48)=111000001001001001110010011000100101110101100010
    k7(48)=101001001101001001110010100011001010100100111010
    k8(48)=101001100101001101010010111001010101111001010000
    k9(48)=001001100101001101010011110010111001101001000000
    k10(48)=001011110101000101010001110100001100011100111100
    k11(48)=000011110100000111011001000110010001111010001100
    k12(48)=000111110100000110011001110110000111000010110001
    k13(48)=000111110000100110001001001000110110101000101101
    k14(48)=000110110010100010001101101100100011100110010010
    k15(48)=000110010010110010001100101001010000001100110111
    k16(48)=010100010010110010001100101001110100001111000000
    

    对密钥的处理完毕,下面开始对明文处理。

    明文

    M=00110000 00110001 00110010 00110011 00110100 00110101 00110110 00110111

    IP置换

    IP置换表(IP)8*8:

    //IP置换表
    int IP[64]={
        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
        };
    

    将明文打乱顺序,得到

    M_IP(64)=00000000 11111111 11110000 10101010 00000000 11111111 00000000 11001100
    

    再将其分为两部分L0、R0

    L0(32)=00000000 11111111 11110000 10101010
    R0(32)=00000000 11111111 00000000 11001100
    

    接下来,从L0R0开始推L1R1,一共循环16次,推出L1-L16
    根据下面的运算规则:

    Ln=R(n-1);
    Rn=L(n-1)异或P( S ( ( E ( R(n-1) ) 异或 Kn ) ) );
    

    L很好得到,就是L1=R0;L2=R1;L3=R2…

    L16R16的运算

    拓展置换

    为了得到R1,首先执行最里面的E(R0)

    选择运算/拓展置换(E)8*6:

    //r数组拓展置换表
    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
        };
    

    将32位的R0拓展到48位

    R0(32)=00000000 11111111 00000000 11001100
    R0(48)=00000000 00010111 11111110 10000000 00010110 01011000
    

    接下来进行 E(R0)异或K1(48)

    k1(48)=010100000010110010101100010101110010101011000010
    E(R0)异或K1(48)=01010000 00111011 01010010 11010111 00111100 10011010
    

    S盒

    接下来进行 S(E(R0)异或K1(48))
    代替函数S盒(S_box):

    //l数组s盒置换表
    int s_box[8][4][16]={
        14,4,13,1,2,15,11,8,3,10,6,12,5,9,0,7,  //s1
        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,
    
        15,1,8,14,6,11,3,4,9,7,2,13,12,0,5,10,  //s2
        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,1,3,15,4,2,11,6,7,12,0,5,14,9,
    
        10,0,9,14,6,3,15,5,1,13,12,7,11,4,2,8,  //s3
        13,7,0,9,3,4,6,10,2,8,5,14,12,11,15,1,
        13,6,4,9,8,15,3,0,11,1,2,12,5,10,14,7,
        1,10,13,0,6,9,8,7,4,15,14,3,11,5,2,12,
    
        7,13,14,3,0,6,9,10,1,2,8,5,11,12,4,15,  //s4
        13,8,11,5,6,15,0,3,4,7,2,12,1,10,14,9,
        10,6,9,0,12,11,7,13,15,1,3,14,5,2,8,4,
        3,15,0,6,10,1,13,8,9,4,5,11,12,7,2,14,
    
        2,12,4,1,7,10,11,6,8,5,3,15,13,0,14,9,  //s5
        14,11,2,12,4,7,13,1,5,0,15,10,3,9,8,6,
        4,2,1,11,10,13,7,8,15,9,12,5,6,3,0,14,
        11,8,12,7,1,14,2,13,6,15,0,9,10,4,5,3,
    
        12,1,10,15,9,2,6,8,0,13,3,4,14,7,5,11,  //s6
        10,15,4,2,7,12,9,5,6,1,13,14,0,11,3,8,
        9,14,15,5,2,8,12,3,7,0,4,10,1,13,11,6,
        4,3,2,12,9,5,15,10,11,14,1,7,6,0,8,13,
    
        4,11,2,14,15,0,8,13,3,12,9,7,5,10,6,1,  //s7
        13,0,11,7,4,9,1,10,14,3,5,12,2,15,8,6,
        1,4,11,13,12,3,7,14,10,15,6,8,0,5,9,2,
        6,11,13,8,1,4,10,7,9,5,0,15,14,2,3,12,
    
        13,2,8,4,6,15,11,1,10,9,3,14,5,0,12,7,  //s8
        1,15,13,8,10,3,7,4,12,5,6,11,0,14,9,2,
        7,11,4,1,9,12,14,2,0,6,10,13,15,3,5,8,
        2,1,14,7,4,10,8,13,15,12,9,0,3,5,6,11
    };
    

    首先将上一步的结果:

    E(R0)异或K1(48)=01010000 00111011 01010010 11010111 00111100 10011010
    

    分为8个6位的数据块

    1010100      2000011     3101101      4010010
    5110101      6110011     7110010      8011010
    

    对第1块处理,将6位中的第1位和第6位组成一个二进制数00,转为十进制数X=0*2+0=0 。再将中间四位1010组成二进制数,转为十进制Y=1*8+0*4+1*2+0*1=10 。X作为行数,Y作为列数,第几块就去找第几盒,那这个块的结果就是S1的0行10列,即S_box[0][0][10],结果为6,将6转为二进制0110 。
    再对其余7块处理完成后,可以得到4*8=32位的结果:

    S(E(R0)异或K1(48))(32)=01101101 10000010 00001110 11110000
    

    P置换

    再进行P(S(E(R0)异或K1(48)))
    置换运算(P)8*4:

    //P盒置换
    int p[32]={
    16,7,20,21,29,12,28,17,
    1,15,23,26,5,18,31,10,
    2,8,24,14,32,27,3,9,
    19,13,30,6,22,11,4,25
    };
    

    这个跟置换选择就一样了,可以得到结果:

    P(S(E(R0)异或K1(48))(32))(32)=00010010 01111000 11000111 00011001
    

    最后将这个结果和L0进行异或操作:

    R1 = L0 异或 P(S(E(R0)异或K1(48))(32))(32)
    L0(32)=00000000 11111111 11110000 10101010
    
    R1(32)=00010010 10000111 00110111 10110011
    L1(32)=R0=00000000 11111111 00000000 11001100
    

    按照拓展置换、S置换、P置换的顺序退出来L16和R16:

    N=1
    L1=00000000111111110000000011001100
    R1=00010010100001110011011110110011
    N=2
    L2=00010010100001110011011110110011
    R2=11100001100111001000011010001010
    N=3
    L3=11100001100111001000011010001010
    R3=11010110001011101111011101100101
    N=4
    L4=11010110001011101111011101100101
    R4=00011110111001010111111100100110
    N=5
    L5=00011110111001010111111100100110
    R5=01011000010000001110001001011100
    N=6
    L6=01011000010000001110001001011100
    R6=00011010011000000110100000101100
    N=7
    L7=00011010011000000110100000101100
    R7=11010001011100100100110001010100
    N=8
    L8=11010001011100100100110001010100
    R8=01101001101101100001001111111010
    N=9
    L9=01101001101101100001001111111010
    R9=10101110100001011111100010000110
    N=10
    L10=10101110100001011111100010000110
    R10=00010101101110011000100100011001
    N=11
    L11=00010101101110011000100100011001
    R11=00010011011001010001111111011000
    N=12
    L12=00010011011001010001111111011000
    R12=11110000111011000111011010001110
    N=13
    L13=11110000111011000111011010001110
    R13=00100111110111000010101111001011
    N=14
    L14=00100111110111000010101111001011
    R14=00011000111101010110001110010100
    N=15
    L15=00011000111101010110001110010100
    R15=00110011111101101010110101000101
    N=16
    L16=00110011111101101010110101000101
    R16=11010100000101101000101010100001
    

    我们需要的就是L16和R16,将它们按R16L16的顺序拼接在一起组成64位数据。

    (64)1101010000010110100010101010000100110011111101101010110101000101
    

    IP逆置换

    //IP逆置换表
    int IP_[64]={
        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
        };
    

    按此表对上步结果进行最后的置换,得到最终的密文:

    C(64)=10001011 10110100 01111010 00001100 11110000 10101001 01100010 01101101
    

    解密

    解密过程其实跟加密过程一样,就是把明文换成密文,密钥不变,再按这个顺序来一遍,但有一点不同的地方
    首先根据密文来获得16个子密钥,不过这16个子密钥跟你明文加密过程中得到的是一样的;
    然后对密文进行操作,IP置换,获得L0R0,在进行16次递推运算时有不同,
    明文加密的运算规则是:

    Ln=R(n-1);
    Rn=L(n-1)异或P( S ( ( E ( R(n-1) ) 异或 Kn ) ) );
    

    密文解密的运算规则是:

    Ln=R(n-1);
    Rn=L(n-1)异或P( S ( ( E ( R(n-1) ) 异或 K(16-n+1) ) ) );
    

    即明文在获取R1时,使用的是子密钥K1
    密文在获取R1时,使用的是子密钥K16,获取R2使用K15
    然后依次进行S盒、P置换、IP逆置换可以得到明文

    N=1
    L1=00110011111101101010110101000101
    R1=00011000111101010110001110010100
    N=2
    L2=00011000111101010110001110010100
    R2=00100111110111000010101111001011
    N=3
    L3=00100111110111000010101111001011
    R3=11110000111011000111011010001110
    N=4
    L4=11110000111011000111011010001110
    R4=00010011011001010001111111011000
    N=5
    L5=00010011011001010001111111011000
    R5=00010101101110011000100100011001
    N=6
    L6=00010101101110011000100100011001
    R6=10101110100001011111100010000110
    N=7
    L7=10101110100001011111100010000110
    R7=01101001101101100001001111111010
    N=8
    L8=01101001101101100001001111111010
    R8=11010001011100100100110001010100
    N=9
    L9=11010001011100100100110001010100
    R9=00011010011000000110100000101100
    N=10
    L10=00011010011000000110100000101100
    R10=01011000010000001110001001011100
    N=11
    L11=01011000010000001110001001011100
    R11=00011110111001010111111100100110
    N=12
    L12=00011110111001010111111100100110
    R12=11010110001011101111011101100101
    N=13
    L13=11010110001011101111011101100101
    R13=11100001100111001000011010001010
    N=14
    L14=11100001100111001000011010001010
    R14=00010010100001110011011110110011
    N=15
    L15=00010010100001110011011110110011
    R15=00000000111111110000000011001100
    N=16
    L16=00000000111111110000000011001100
    R16=00000000111111111111000010101010
    解密后的明文为:
    00110000 00110001 00110010 00110011 00110100 00110101 00110110 00110111
    

    对比明文

    M=00110000 00110001 00110010 00110011 00110100 00110101 00110110 00110111
    

    结果正确


    代码:C语言DES加密解密代码

    展开全文
  • DES加密解密算法C语言实现,只要调用函数,即可实现数据的加密解密,我已经在DSP上实现。
  • 用vs2012写的,可以直接运行想要代码的话,都在一个cpp文件中
  • c语言实现DES加密解密

    2021-09-17 15:41:17
    c语言实现DES加密解密欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、...
    #ifndef DES_H
    #define DES_H
    
    #ifdef __cplusplus
    extern "C"
    {
    #endif
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <stdbool.h>
    
    #define RESET_BIT_NUMBER(UA, BIT_NUMBER) ( (UA) &= ( ~ ( 1 << (BIT_NUMBER) ) ) )
    #define SET_BIT_NUMBER(UA, BIT_NUMBER) ( (UA) |= ( 1 << (BIT_NUMBER) ) )
    #define BIT_JUDGE(UA, BIT_NUMBER) ( ( (UA) >> (BIT_NUMBER) ) & 1 )
    
    #define des_standard 64
    #define des_key_pc1_standard 56
    #define des_key_pc2_standard 48 
    #define des_data_rl 32 
    #define NumberOfKeys 16
    #define systemBit 8
    
    #define Table_size unsigned char 
    #define data_lenght_size unsigned int 
    #define data_size unsigned char
    #define subkey_size unsigned long long 
    
    data_size *__desSubKeyGeneration(data_size *key, data_lenght_size key_lenght);
    data_size *__desDataEncryption(data_size *data, data_lenght_size data_lenght, data_size *key, data_lenght_size key_lenght);
    data_size *__desDataDecrypt(data_size *data, data_lenght_size data_lenght, data_size *key, data_lenght_size key_lenght);
    
    #ifdef __cplusplus
    }
    #endif
    
    #endif //DES_H
    
    #include "des.h"
    
    //移位表
    static Table_size const shiftTable[NumberOfKeys] = {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1};
    
    //E扩展表
    static Table_size const eTable[des_key_pc2_standard]={
    	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
    };
    
    //P置换表
    static Table_size const pTable[des_data_rl]={
    	16, 7,20,21,29,12,28,17, 
        1,15,23,26, 5,18,31,10,
    	2, 8,24,14,32,27, 3, 9,
        19,13,30, 6,22,11, 4,25
    };
    
    //数据初始置换表
    static Table_size const ip0Table[des_standard] = {
        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
    };
    
    //ip1表
    static Table_size const ip1Table[des_standard]={              
    	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 
    };
    
    //子密钥pc1置换表
    static Table_size const desSubkeyPc1[des_key_pc1_standard] = {
        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
    };
    
    //子密钥pc2置换表
    static Table_size const desSubkeyPc2[des_key_pc2_standard]={
    	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, 34, 33, 48, 44, 49, 39, 56,
        34, 53, 46, 42, 50, 36, 29, 32 
    };
    
    //S盒表
    static Table_size const sBoxTable[8][4][16]={
     //S1
    	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,
     //S2
    	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,  1,  3, 15,  4,  2, 11, 6,  7, 12,  0, 5, 14,  9,
     //S3
    	10,  0,  9, 14, 6,  3, 15,  5,  1, 13, 12,  7, 11,  4,  2,  8,
    	13,  7,  0,  9, 3,  4,  6, 10,  2,  8,  5, 14, 12, 11, 15,  1,
    	13,  6,  4,  9, 8, 15,  3,  0, 11,  1,  2, 12,  5, 10, 14,  7,
    	 1, 10, 13,  0, 6,  9,  8,  7,  4, 15, 14,  3, 11,  5,  2, 12,
     //S4
    	 7, 13, 14, 3,  0,  6,  9, 10,  1, 2, 8,  5, 11, 12,  4, 15,
    	13,  8, 11, 5,  6, 15,  0,  3,  4, 7, 2, 12,  1, 10, 14,  9,
    	10,  6,  9, 0, 12, 11,  7, 13, 15, 1, 3, 14,  5,  2,  8,  4,
    	 3, 15,  0, 6, 10,  1, 13,  8,  9, 4, 5, 11, 12,  7,  2, 14,
     //S5
    	 2, 12,  4,  1,  7, 10, 11,  6,  8,  5,  3, 15, 13, 0, 14,  9,
    	14, 11,  2, 12,  4,  7, 13,  1,  5,  0, 15, 10,  3, 9,  8,  6,
    	 4,  2,  1, 11, 10, 13,  7,  8, 15,  9, 12,  5,  6, 3,  0, 14,
    	11,  8, 12,  7,  1, 14,  2, 13,  6, 15,  0,  9, 10, 4,  5,  3,
     //S6
    	12,  1, 10, 15, 9,  2,  6,  8,  0, 13,  3,  4, 14,  7,  5, 11,
    	10, 15,  4,  2, 7, 12,  0,  5,  6,  1, 13, 14,  0, 11,  3,  8,
    	9,  14, 15,  5, 2,  8, 12,  3,  7,  0,  4, 10,  1, 13, 11,  6,
    	4,   3,  2, 12, 9,  5, 15, 10, 11, 14,  1,  7,  6,  0,  8, 13,
     //S7
    	4,11, 2,14,15, 0, 8,13, 3,12, 9, 7, 5,10, 6, 1,
    	13, 0,11, 7, 4, 0, 1,10,14, 3, 5,12, 2,15, 8, 6,
    	1, 4,11,13,12, 3, 7,14,10,15, 6, 8, 0, 5, 9, 2,
    	6,11,13, 8, 1, 4,10, 7, 9, 5, 0,15,14, 2, 3,12,
     //S8
    	13, 2, 8, 4, 6,15,11, 1,10, 9, 3,14, 5, 0,12, 7,
    	1,15,13, 8,10, 3, 7, 4,12, 5, 6,11, 0,14, 9, 2,
    	7,11, 4, 1, 9,12,14, 2, 0, 6,10,13,15, 3, 5, 8,
    	2, 1,14, 7, 4,10, 8,13,15,12, 9, 0, 3, 5, 6,11
    };
    
    data_size *__desSubKeyGeneration(data_size *key, data_lenght_size key_lenght)
    {
        //如果传入空或长度不为8字节则返回空
        if(key==NULL || key_lenght!=8)
            return NULL;
        //申请堆内存
        data_size *subkey16 = (data_size *)malloc(NumberOfKeys * (des_key_pc2_standard / systemBit));
        //清空初始化,按照申请内存大小来清空这块堆内存
        memset(subkey16, 0, NumberOfKeys * (des_key_pc2_standard / systemBit));
        //创建布尔型的数组
        int count = 0;
        bool tmp = 0;
        bool bit_table_pc1[des_key_pc1_standard]={0};
        bool bit_table[des_standard]={0};
        //将数据赋值到布尔型数组里面
        for(int i=0; i<des_standard; i++)
            bit_table[i] = BIT_JUDGE(*(key + i / systemBit), (i % systemBit));
        //进行PC1转换
        for(int i=0; i<des_key_pc1_standard; i++)
            bit_table_pc1[i] = bit_table[desSubkeyPc1[i]-1];
        //进行十六次密钥生成
        for(int num=0; num<NumberOfKeys; num++)
        {
            //保存移位次数
            count = shiftTable[num];
            //进行移位
            while(count--)
            {
                //前二十八位移位
                tmp = bit_table_pc1[0];
                for(int i=0; i<28; i++)
                    bit_table_pc1[i]=bit_table_pc1[i+1];
                bit_table_pc1[27]=tmp;
                //后二十八位移位
                tmp = bit_table_pc1[28];
                for(int i=28; i<56; i++)
                    bit_table_pc1[i]=bit_table_pc1[i+1];
                bit_table_pc1[55]=tmp;
            }
            //进行判断写入新的数据
            for(int i=0; i<des_key_pc2_standard; i++)
            {
                if(bit_table_pc1[desSubkeyPc2[i]-1])
                    SET_BIT_NUMBER(*(subkey16 + (num * (des_key_pc2_standard / systemBit)) + (i / systemBit)), (i % systemBit));
                else RESET_BIT_NUMBER(*(subkey16 + (num * (des_key_pc2_standard / systemBit)) + (i / systemBit)), (i % systemBit));
            }
        }
        return subkey16;
    }
    
    data_size *__desDataEncryption(data_size *data, data_lenght_size data_lenght, data_size *key, data_lenght_size key_lenght)
    {
        //如果传入空或长度不为8字节则返回空
        if(key==NULL || key_lenght!=(NumberOfKeys*(des_key_pc2_standard/systemBit)) || data==NULL || data_lenght!=8)
            return NULL;
        //申请堆内存
        data_size *Data16 = (data_size *)malloc(des_standard);
        //清空初始化,按照申请内存大小来清空这块堆内存
        memset(Data16, 0, des_standard);
        //创建一个布尔型的数组
        bool bit_table[des_standard]={0};
        bool data64_table[des_standard]={0};
        bool extend48_table[des_key_pc2_standard]={0};
        bool dataL32_table[des_data_rl]={0};
        bool dataR32_table[des_data_rl]={0};
        bool tmpL32_table[des_data_rl]={0};
        bool tmpR32_table[des_data_rl]={0};
        //将数据赋值到布尔型数组里面
        for(int i=0; i<des_standard; i++)
            bit_table[i] = BIT_JUDGE(*(data + (i / systemBit)), (i % systemBit));
        //进行初始置换
        for(int i=0; i<des_standard; i++)
            data64_table[i] = bit_table[ip0Table[i]-1];
        //将64位一分为二
        for(int i=0; i<des_data_rl; i++)
            dataL32_table[i] = data64_table[i];
        for(int i=0; i<des_data_rl; i++)
            dataR32_table[i] = data64_table[i+32];
        //   列    行
        int row=0, col=0;
        //进行十六次轮函数
        for(int num=0; num<NumberOfKeys; num++)
        {
            //将R数组赋值给L的临时数组
            for(int i=0; i<des_data_rl; i++) 
                tmpL32_table[i] = dataR32_table[i];
            //将R数组进行E扩展
            for(int i=0; i<des_key_pc2_standard; i++)
                extend48_table[i] = dataR32_table[(eTable[i]-1)];
            //将E扩展后48位和子密钥进行异或
            for(int i=0; i<des_key_pc2_standard; i++) 
                extend48_table[i] = extend48_table[i] ^ (BIT_JUDGE(*(key + (num * (des_key_pc2_standard / systemBit)) + i / systemBit), (i % systemBit)));  
            //将48位转换成32位
            for(int j=0; j<des_key_pc2_standard; j+=6) 
            {
                //计算出行列
                row = extend48_table[j+0]*2 + extend48_table[j+5]*1;
                col = extend48_table[j+1]*8 + extend48_table[j+2]*4 + extend48_table[j+3]*2 + extend48_table[j+4]*1;
                //进行查表,并将10进制转换为四位二进制
                for(int i=0; i<4; i++) 
                    dataR32_table[((j/6)*4)+i] = BIT_JUDGE(sBoxTable[j/6][row][col], i);
            }
            //将R进行转换并存入R临时数组
            for(int i=0; i<des_data_rl; i++) 
                tmpR32_table[i] = dataR32_table[pTable[i]-1];
            //在用临时数组进行异或
            for(int i=0; i<des_data_rl; i++)
            {
                dataR32_table[i] = (dataL32_table[i] ^ tmpR32_table[i]);
            }
            //最后将刚才的L临时数组赋值
            for(int i=0; i<des_data_rl; i++)
                dataL32_table[i] = tmpL32_table[i];
        }
        //将两个32位进行拼接
        for(int i=0; i<des_data_rl; i++)
            data64_table[i] = dataL32_table[i];
        for(int i=des_data_rl; i<des_standard; i++)
            data64_table[i] = dataR32_table[i-32];
        //进行判断写入新的数据
        for(int i=0; i<des_standard; i++)
        {
            if(data64_table[ip1Table[i]-1])
                SET_BIT_NUMBER(*(Data16 + (i / systemBit)), (i % systemBit));
            else RESET_BIT_NUMBER(*(Data16 + (i / systemBit)), (i % systemBit));
        }
        return Data16;
    }
    
    data_size *__desDataDecrypt(data_size *data, data_lenght_size data_lenght, data_size *key, data_lenght_size key_lenght)
    {
        //如果传入空或长度不为8字节则返回空
        if(key==NULL || key_lenght!=(NumberOfKeys*(des_key_pc2_standard/systemBit)) || data==NULL || data_lenght!=8)
            return NULL;
        //申请堆内存
        data_size *Data16 = (data_size *)malloc(des_standard);
        //清空初始化,按照申请内存大小来清空这块堆内存
        memset(Data16, 0, des_standard);
        //创建一个布尔型的数组
        bool bit_table[des_standard]={0};
        bool data64_table[des_standard]={0};
        bool extend48_table[des_key_pc2_standard]={0};
        bool dataL32_table[des_data_rl]={0};
        bool dataR32_table[des_data_rl]={0};
        bool tmpL32_table[des_data_rl]={0};
        bool tmpR32_table[des_data_rl]={0};
        //将数据赋值到布尔型数组里面
        for(int i=0; i<des_standard; i++)
            bit_table[i] = BIT_JUDGE(*(data + (i / systemBit)), (i % systemBit));
        //进行初始置换
        for(int i=0; i<des_standard; i++)
            data64_table[i] = bit_table[ip0Table[i]-1];
        //将64位一分为二
        for(int i=0; i<des_data_rl; i++)
            dataR32_table[i] = data64_table[i];
        for(int i=0; i<des_data_rl; i++)
            dataL32_table[i] = data64_table[i+32];
        //   列    行
        int row=0, col=0;
        //进行十六次轮函数
        for(int num=(NumberOfKeys-1); num>=0; num--)
        {
            //将R数组赋值给L的临时数组
            for(int i=0; i<des_data_rl; i++) 
                tmpL32_table[i] = dataR32_table[i];
            //将R数组进行E扩展
            for(int i=0; i<des_key_pc2_standard; i++)
                extend48_table[i] = dataR32_table[(eTable[i]-1)];
            //将E扩展后48位和子密钥进行异或
            for(int i=0; i<des_key_pc2_standard; i++) 
                extend48_table[i] = extend48_table[i] ^ (BIT_JUDGE(*(key + (num * (des_key_pc2_standard / systemBit)) + i / systemBit), (i % systemBit)));  
            //将48位转换成32位
            for(int j=0; j<des_key_pc2_standard; j+=6) 
            {
                //计算出行列
                row = extend48_table[j+0]*2 + extend48_table[j+5]*1;
                col = extend48_table[j+1]*8 + extend48_table[j+2]*4 + extend48_table[j+3]*2 + extend48_table[j+4]*1;
                //进行查表,并将10进制转换为四位二进制
                for(int i=0; i<4; i++) 
                    dataR32_table[((j/6)*4)+i] = BIT_JUDGE(sBoxTable[j/6][row][col], i);
            }
            //将R进行转换并存入R临时数组
            for(int i=0; i<des_data_rl; i++) 
                tmpR32_table[i] = dataR32_table[pTable[i]-1];
            //在用临时数组进行异或
            for(int i=0; i<des_data_rl; i++) 
            {
                dataR32_table[i] = (dataL32_table[i] ^ tmpR32_table[i]);
            }
            //最后将刚才的L临时数组赋值
            for(int i=0; i<des_data_rl; i++) 
                dataL32_table[i] = tmpL32_table[i];
        }
        //将两个32位进行拼接
        for(int i=0; i<des_data_rl; i++)
            data64_table[i] = dataR32_table[i];
        for(int i=des_data_rl; i<des_standard; i++)
            data64_table[i] = dataL32_table[i-32];
        //进行判断写入新的数据
        for(int i=0; i<des_standard; i++)
        {
            if(data64_table[ip1Table[i]-1])
                SET_BIT_NUMBER(*(Data16 + (i / systemBit)), (i % systemBit));
            else RESET_BIT_NUMBER(*(Data16 + (i / systemBit)), (i % systemBit));
        }
        return Data16;
    }
    
    #include "des.h"
    #include <stdio.h>
    
    int main(void)
    {
        data_size key[8] = {0x21,'4','5',0x44,'4','5','6','7'};
        data_size data[8] = {'1','2','3','4','5','6','7','8'};
    
        data_size *subkey16 = __desSubKeyGeneration((data_size *)key, 8);
        data_size *mdata = __desDataEncryption((data_size *)data, 8, subkey16, 6*16);
        data_size *ydata = __desDataDecrypt(mdata, 8, subkey16, 6*16);
    
        printf("加密后数据十六进制:");
        for(int num=0; num<8; num++)
            printf("0x%02X ",*(mdata+num));
        printf("\n");
        printf("解密后原数据:");
        for(int num=0; num<8; num++)
            printf("%c ",*(ydata+num));
        printf("\n");
        return 0;
    }
    
    展开全文
  • C语言版本的3DES加密解密算法(用DEV C++编译和运行过代码),纯粹的C语言版本,我自己也编译通过,利用DEV C++运行过.希望给大家以帮助!
  • C语言实现了DES、三重DES(3DES)的加解密,支持ECB、CBC模式。 ECB支持64位密钥; CBC支持128和192位密钥
  • 纠正了过去下载DES源码中加解密中文字符错误的代码,使用VS2010编译测试通过。
  • 基于STM32的软件加解密算法,包括DES,3DES的ECB,CBC模式。但是验证时CBC模式的初始向量为0时,数据的加解密正确,但是初始向量不为0时,则加解数据有错误。 注意:经测试DES,3DES的CBC模式初始向量不为0时,加...
  • DES加密解密算法 C语言源代码,STM32 51单片机可用。提高产品的安全性,RAM占用小。 /* DES加密,binput:明文,boutput:密文, bkey:密钥 */
  • DES算法全解 一、什么是DES算法 DES是(Data Encryption Standard)的缩写,为密码体制中的对称密码体制,又被称为美国数据加密标准。 DES是一种分组密码。明文,密文,密钥的分组长度都是64位。 DES是面向二进制的...

    如果想要更好阅读体验,可以进入我个人博客

    DES算法全解

    一、什么是DES算法

    • DES是(Data Encryption Standard)的缩写,为密码体制中的对称密码体制,又被称为美国数据加密标准。
    • DES是一种分组密码。明文,密文,密钥的分组长度都是64位。
    • DES是面向二进制的密码算法。因而能够加解密任何形式的计算机数据。
    • DES是对合运算,因而加密和解密共用同一算法,从而使工程实现的工作量减半
    • DES的密码结构属于Feistel结构

    二、DES的加密过程

    1. 64位秘钥经子秘钥产生算法产生出16个子秘钥: K 1 , K 2 , . . . , K 16 K_1,K_2,...,K_{16} K1,K2,...,K16, 分别供第一次,第二次,… ,第十六次加密迭代使用。
    2. 64位明文首先经过初始置换 I P ( I n i t i a l p e r m u t a t i o n ) IP(Initial\quad permutation) IPInitialpermutation,将数据打乱重新排列并分成左右两半,左边32位构成 L 0 L_0 L0,右边32位构成 R 0 R_0 R0
    3. 由加密函数 f f f实现子密钥 K 1 K_1 K1 R 0 R_0 R0的加密,结果为32位的数据组 f ( R 0 , K 1 ) f(R_0,K_1) f(R0,K1) f ( R 0 , K 1 ) f(R_0,K_1) f(R0,K1)再与 L 0 L_0 L0模2相加,又得到一个有32位的数据组 L 0 ⨁ f ( R 0 , K 1 ) L_0\bigoplus f(R_0,K_1) L0f(R0,K1)。以 L 0 ⨁ f ( R 0 , K 1 ) L_0\bigoplus f(R_0,K_1) L0f(R0,K1)作为第二次加密迭代的 R 1 R_1 R1,以 R 0 R_0 R0作为第二次加密迭代的 L 1 L_1 L1。至此,第一次加密迭代结束。
    4. 第二次加密迭代至第十六次加密迭代分别用子密钥 K 2 , . . . , K 16 K_2,...,K_{16} K2...K16进行,其过程与第一次加密迭代相同。
    5. 第十六次加密迭代结束后,产生一个64位的数据组。以其左边32位作为 L 16 L_{16} L16,以其右边32位作为 R 16 R_{16} R16,两者合并在经过逆初始置换** I P − 1 \color{red}{IP^{-1} } IP1**,将数据重新排列,便得到64位密文。至此加密过程全部结束。

    三、DES的算法细节

    下面我们详细的介绍算法细节。

    1. 创建16个子秘钥,每个长48比特

    创建子密钥过程大致流程图如下:

    流程

    64位秘钥我们已经给出,现在依次介绍置换选择1,,置换选择2,循环左移。

    1. 置换选择1

      • 64位秘钥分为8个字节,每个字节的前7位是真正的秘钥位,第8位是奇偶校验位。奇偶校验位可以从前7位秘钥位计算得出,不是随机的,因而不起秘钥的作用。奇偶校验位的作用在于可检测秘钥中是否有错误,确保秘钥的完整性,因此,DES真正的秘钥只有56位。

      • 置换选择1的作用,一是从64位秘钥中去掉8个奇偶校验位,二是把其余56位秘钥位打乱重新排,且将前28位作为 C 0 C_0 C0,后28位作为 D 0 D_0 D0

      • 置换选择1规定: C 0 C_0 C0的各位依次为原秘钥中的第57,49,…,1,…,44,36位。 D 0 D_0 D0的各位依次为原秘钥中的第63,55,…,7,…,12,4位,具体矩阵如下:

        [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-U9koJNCD-1618738451125)(https://i.loli.net/2021/04/13/oDOfBns9UCNzHa4.jpg)]

    例:秘钥为12345678

    以ASCLL码的形式转化为二进制:

    00110001 00110010 00110011 00110100 00110101 00110110 00110111 00111000
    

    那么,此秘钥置换选择1后的结果为:

    置换选择1:

    00000000 00000000 11111111 11110110 01100111 1001000 00001111
    

    C 0 C_0 C0

    0000000000000000111111111111
    

    D 0 D_0 D0

    0110011001111000100000001111
    
    1. 置换选择2
      • C i C_i Ci D i D_i Di合并成一个56位的中间数据,置换选择2从中选择出一个48位的子密钥 K i K_i Ki。置换选择2的矩阵如下图
      • 置换选择2规定子密钥 K i K_i Ki中的第1,2,…,48位依次是这个56位中间数据中的第14,17,…,5,3,…,29,32位。
    置换选择2
    1. 循环左移:将密钥(除第一位)整体左移一位,将第一位移动至最后一位。循环左移位数表如下:循环左移位数表

    16轮子密钥生成结果如下:

    2. 明文初始变换

    初始置换 I P IP IP是DES的第一步密码变换,初始置换的作用在于将64位明文打乱重排,并陈诚左右两半,左边32位作为 L 0 L_0 L0,右边32位作为 R 0 R_0 R0。供后面的加密迭代使用。初始置换 I P IP IP的矩阵如下:(道理同上)

    初始置换IP

    3. 加密函数

    加密函数是DES的核心部分。它的作用是在第 i i i次加密迭代中用子密钥 K i K_i Ki R i − 1 R_{i-1} Ri1进行加密。

    在第 i i i次迭代加密中选择运算 E E E对32位的 R i − 1 R_{i-1} Ri1的各位进行选择和排列,产生一个48位的结果,此结果与子密钥 K i K_i Ki模2相加,然后送入代替函数组 S S S。代替函数组由8个代替函数(也称S盒子)组成,每个S盒子有6位输入,产生4位的输出。8个S盒子的输出合并,结果得到一个32位的数据组。此数据组在经过置换运算P,将其各位打乱重排,置换运算P的输出便是加密函数的输出 f ( R i − 1 , K i ) f(R_{i-1},K_i) f(Ri1,Ki)

    1. 选择运算E对32位的数据组A的各位进行选择和排列,产生一个48位的结果。他是一种扩展运算,其矩阵如图:

      选择运算
    2. 代替函数组S由8个代替函数(也称S盒子)组成,8个S盒分别记为, S 1 , S 2 , . . . , S 8 S_1,S_2,...,S_8 S1,S2,...,S8。代替函数组的输入时一个48位的数据,从第一位到第48位依次加到8个S盒的输入端,每个S盒有一个代替矩阵,规定了其输出与输入的代替规则。代替矩阵有4行16列,每行都是0到15这16个数字,但每行的数字排列都不同,而且8个代替矩阵彼此也不同,每个S盒有6位输入,产生4位的输出。S盒运算的结果是用输出数据代替了输入数据,所以称其为代替函数。

      ​ **S盒的代替规则:**S盒的六位输入中,第一位和第六位组成二进制数并转化为十进制数代表选中的行号,其余四位组成二进制数并转化为十进制数代表选中的列号。那么被选中的那个数就是要输出的数(转化为二进制)。

      ​ 以 S 1 S_1 S1为例,如果输入的是101011,第一位与第六位组成行号 1 1 ( 2 ) = 3 ( 10 ) 11_{(2)} = 3_{(10)} 11(2)=3(10) ,选中第三行,其余四位组成列号 010 1 ( 2 ) = 5 ( 10 ) 0101_{(2)} = 5_{(10)} 0101(2)=5(10),选中第五列,交点数字是9,则 S 1 S_1 S1的输出是1001。

    3. **置换运算 P P P:**置换运算吧S盒输出的32位数据打乱重排,得到32位的加密函数输出。用P置换来提供扩散,把S盒的混淆作用扩散开来。此时, R i − 1 R_{i-1} Ri1变成 L i L_{i} Li L i L_i Li再和置换运算P得出来的32位数据做 ⨁ \bigoplus 运算,得到 R i R_i Ri。置换矩阵如图:

    4. **逆初始置换 I P − 1 IP^{-1} IP1:**是初始置换的逆置换,它把第十六次加密迭代的结果打乱重排(这里 R 16 R_{16} R16 L 16 L_{16} L16互换),形成64位密文。至此,加密过程完全结束。

    672C1E7DBC59E27A94DF29AF58498D4B.jpg 4C5C280892CC879204AC6F800285FC99.jpg 930EEC1CD39D6D844DFD3167F84CFBC4.jpg 3AF7BA7A091100A2732266480E846A0A.jpg

    4. 解密过程

    ​ 由于DES是对合运算,所以解密和加密可共用同一个运算,只是子密钥使用的顺序不同。把64位密文当做明文输入,而且第一次解密迭代是用子密钥 K 16 K_{16} K16,第十六次解密迭代使用子密钥 K 1 K_1 K1,最后的输出便是64位明文。

    代码如下:

    //
    //  main.cpp
    //  DES算法
    //
    //  Created by CharlesYan on 2021/4/13.
    //
    
    #include <iostream>
    #include <stdio.h>
    #include<stdlib.h>
    using namespace std;
    //16-wheel secret key structural body
    struct Secret_Key{
        int subKey[56] = {};
        int C[28];
        int D[28];
    }Secret_KeyOf16[17];//save the 16-wheel sercet key,and the zero flag in order to save the first substitution selection.
    
    // save the process of encryption
    struct Encryption{
        int select_Operation[48];
        int secretKey_Operation[48];
        int boxOf_S[32];
        int L[32];
        int R[32];
    }Encryption_Pro[17];
    
    int result_Secret[64] = {};
    
    
    
    //substitution selection table 1(置换选择1)
    static int subSelect_table1[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
       };
    //substitution selection table 2(置换选择2)
    static int subSelect_table2[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
    };
    //Move left shift bits table(循环左移位数表)
    static int moveLeft_table[17] = {0,1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1};
    //initial substitution IP
    static int init_subIP[64] = {
    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
    };
    //selection operation E
    static int sel_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
    };
    // Box of S 3D array
    static int BoxOf_S[8][4][16]={
     //S1
     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,
     //S2
     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, 1, 3,15, 4, 2,11, 6, 7,12, 0, 5,14, 9,
     //S3
     10, 0, 9,14, 6, 3,15, 5, 1,13,12, 7,11, 4, 2, 8,
     13, 7, 0, 9, 3, 4, 6,10, 2, 8, 5,14,12,11,15, 1,
     13, 6, 4, 9, 8,15, 3, 0,11, 1, 2,12, 5,10,14, 7,
      1,10,13, 0, 6, 9, 8, 7, 4,15,14, 3,11, 5, 2,12,
     //S4
      7,13,14, 3, 0, 6, 9,10, 1, 2, 8, 5,11,12, 4,15,
     13, 8,11, 5, 6,15, 0, 3, 4, 7, 2,12, 1,10,14, 9,
     10, 6, 9, 0,12,11, 7,13,15, 1, 3,14, 5, 2, 8, 4,
      3,15, 0, 6,10, 1,13, 8, 9, 4, 5,11,12, 7, 2,14,
     //S5
      2,12, 4, 1, 7,10,11, 6, 8, 5, 3,15,13, 0,14, 9,
     14,11, 2,12, 4, 7,13, 1, 5, 0,15,10, 3, 9, 8, 6,
      4, 2, 1,11,10,13, 7, 8,15, 9,12, 5, 6, 3, 0,14,
     11, 8,12, 7, 1,14, 2,13, 6,15, 0, 9,10, 4, 5, 3,
     //S6
     12, 1,10,15, 9, 2, 6, 8, 0,13, 3, 4,14, 7, 5,11,
     10,15, 4, 2, 7,12, 9, 5, 6, 1,13,14, 0,11, 3, 8,
      9,14,15, 5, 2, 8,12, 3, 7, 0, 4,10, 1,13,11, 6,
         4, 3, 2,12, 9, 5,15,10,11,14, 1, 7, 6, 0, 8,13,
     //S7
      4,11, 2,14,15, 0, 8,13, 3,12, 9, 7, 5,10, 6, 1,
     13, 0,11, 7, 4, 9, 1,10,14, 3, 5,12, 2,15, 8, 6,
      1, 4,11,13,12, 3, 7,14,10,15, 6, 8, 0, 5, 9, 2,
      6,11,13, 8, 1, 4,10, 7, 9, 5, 0,15,14, 2, 3,12,
     //S8
     13, 2, 8, 4, 6,15,11, 1,10, 9, 3,14, 5, 0,12, 7,
      1,15,13, 8,10, 3, 7, 4,12, 5, 6,11, 0,14, 9, 2,
      7,11, 4, 1, 9,12,14, 2, 0, 6,10,13,15, 3, 5, 8,
      2, 1,14, 7, 4,10, 8,13,15,12, 9, 0, 3, 5, 6,11
    };
    //substitution IP
    static char P_Table[32]={
     16, 7,20,21,29,12,28,17, 1,15,23,26, 5,18,31,10,
      2, 8,24,14,32,27, 3, 9,19,13,30, 6,22,11, 4,25
    };
    
    const int IPR_Table[64]={
     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
    };
    
    
    //Convert an 8-byte key or plaintext to 64-bit binary
    int* ChangeToBit(char code[],int n);
    //Subfunction:change Byte to 8-bit binary
    int * Change_bit(int a);
    //create 16-wheel secret key and save them to Secret_KeyOf16
    void set_16wheelKey(int *bit_SecretKey);
    //the first step of encryption,set R0, as we know, we will not need L0 later.
    void first_StepEncryption(int *bit_PlainText);
    //encryption, return the result of encryption
    void other_StepEncrtption(int flag);
    //Box of S operation
    void Box_operation(int *a,int n);
    // Box of S change byte to bit
    int * Change_bit_S(int a);
    //IPR_table operation
    void IPR_Operation(int result[]);
    void print(int flag);
    void Pri_ChangeToByte(int secretKey[]);
    int main() {
        char my_Plaintext[9] = {};//save plaintext and the last one is '\0'
        char my_SecretKey[9] = {};//save secretkey
        cout<<"Please input the plaintext of 8 byte:"<<endl;
        cin.get(my_Plaintext,9);
        cin.get();// getchar();
        cout<<"Please input the secret key of 8 byte"<<endl;
        cin.get(my_SecretKey,9);
        printf("\n");
        //8-byte SecretKey turn into 64-bit binary
        int *bit_SecretKey = ChangeToBit(my_SecretKey, 8);
        //create 16-wheel secret key.
        set_16wheelKey(bit_SecretKey);
        //8-byte SecretKey turn into 64-bit binary
        int *bit_Plaintext = ChangeToBit(my_Plaintext, 8);
        
        //Encryption
        first_StepEncryption(bit_Plaintext);
        other_StepEncrtption(0);//the 0 is meant encryption
        IPR_Operation(result_Secret);
        print(0);
        
        //Decryption
        first_StepEncryption(result_Secret);
        other_StepEncrtption(1);//the 1 is meant decryption.
        IPR_Operation(result_Secret);
        print(0);
        Pri_ChangeToByte(result_Secret);
    }
    int* ChangeToBit(char code[],int n){
        static int BinaryText[64] = {};
        int k = 0;
        for (int i = 0; i<n; i++) {
            int *temp =Change_bit(code[i]);
            for (int j = 0; j<n; j++) {
                BinaryText[k++] = temp[j];
            }
        }
    
        return BinaryText;
    }
    int * Change_bit(int a){
        static int flag[8] = {};
        int k = 7;
        while (a/2!=0) {
            flag[k--] = a % 2;
            a = a / 2;
        }
        flag[k] = 1;
        return flag;
    }
    int * Change_bit_S(int a){
        static int flag[4] = {0};
        int k = 0;
        while (a/2!=0) {
            flag[k++] = a % 2;
            a = a / 2;
        }
        if(a == 1)
        flag[k] = 1;
        return flag;
    }
    void set_16wheelKey(int *bit_SecretKey){
        //substitution selection 1
        for (int i = 0; i<56; i++) {
            Secret_KeyOf16[0].subKey[i] = bit_SecretKey[subSelect_table1[i]-1];
        }
        //C0 D0
        for (int i = 0; i<28; i++) {
            Secret_KeyOf16[0].C[i] = Secret_KeyOf16[0].subKey[i];
            Secret_KeyOf16[0].D[i] = Secret_KeyOf16[0].subKey[i+28];
        }
        for (int i = 1 ; i<17; i++) {
            if(moveLeft_table[i] == 1){
            for (int j = 0; j<27; j++) {
                Secret_KeyOf16[i].C[j] = Secret_KeyOf16[i-1].C[j+1];
                Secret_KeyOf16[i].D[j] = Secret_KeyOf16[i-1].D[j+1];
            }
            Secret_KeyOf16[i].C[27] = Secret_KeyOf16[i-1].C[0];
            Secret_KeyOf16[i].D[27] = Secret_KeyOf16[i-1].D[0];
            }else{
                for (int j = 0; j<26; j++) {
                    Secret_KeyOf16[i].C[j] = Secret_KeyOf16[i-1].C[j+2];
                    Secret_KeyOf16[i].D[j] = Secret_KeyOf16[i-1].D[j+2];
                }
                Secret_KeyOf16[i].C[26] = Secret_KeyOf16[i-1].C[0];
                Secret_KeyOf16[i].C[27] = Secret_KeyOf16[i-1].C[1];
                Secret_KeyOf16[i].D[26] = Secret_KeyOf16[i-1].D[0];
                Secret_KeyOf16[i].D[27] = Secret_KeyOf16[i-1].D[1];
            }
        }
        //subKey1 ... subKey16
        for (int i = 1; i<17; i++) {
            int flag[56] = {};
            for (int j = 0; j<28; j++) {
                flag[j] = Secret_KeyOf16[i].C[j];
                flag[j+28] = Secret_KeyOf16[i].D[j];
            }
            for (int j = 0; j<48; j++) {
                Secret_KeyOf16[i].subKey[j] = flag[subSelect_table2[j]-1];
            }
        }
        //print the result of secret key.
        for (int i = 1; i<17; i++) {
            printf("N = %d\n",i);
            printf("C%d:",i);
            for (int j = 0; j<28; j++) {
                printf("%d",Secret_KeyOf16[i].C[j]);
            }
            printf("\n");
            printf("D%d:",i);
            for (int j = 0; j<28; j++) {
                printf("%d",Secret_KeyOf16[i].D[j]);
            }
            printf("\n");
            printf("子密钥%d:",i);
            for (int j = 0; j<48; j++) {
                if(j%8 == 0 && j) printf(" ");
                printf("%d",Secret_KeyOf16[i].subKey[j]);
            }
            printf("\n\n");
        }
    }
    void first_StepEncryption(int *bit_PlainText){
        for (int i = 0; i<32; i++) {
            Encryption_Pro[0].L[i] = bit_PlainText[init_subIP[i]-1];
            Encryption_Pro[0].R[i] = bit_PlainText[init_subIP[i+32]-1];
        }
    }
    void other_StepEncrtption(int flag){
        for (int i = 1; i<17; i++) {
            for (int j = 0; j<48; j++) {
                //selection
                Encryption_Pro[i].select_Operation[j] = Encryption_Pro[i-1].R[sel_E[j]-1];
                //secretion operation
                if(flag == 0)
                Encryption_Pro[i].secretKey_Operation[j] =Secret_KeyOf16[i].subKey[j]^Encryption_Pro[i].select_Operation[j];
                else
                    Encryption_Pro[i].secretKey_Operation[j] =Secret_KeyOf16[17-i].subKey[j]^Encryption_Pro[i].select_Operation[j];
            }
            // Box of S
            Box_operation(Encryption_Pro[i].secretKey_Operation,i);
            // XOR operation
            for (int j = 0; j<32; j++) {
                Encryption_Pro[i].L[j] = Encryption_Pro[i-1].R[j];
                Encryption_Pro[i].R[j] = Encryption_Pro[i-1].L[j]^Encryption_Pro[i].boxOf_S[P_Table[j]-1];
            }
        }
    }
    void Box_operation(int *a,int n){
        int sum = 0;
        for (int i = 0; i<48; i += 6) {
            int flag1 = BoxOf_S[i/6][a[i]*2+a[i+5]][a[i+1]*8+a[i+2]*4+a[i+3]*2+a[i+4]];
            int flag[4] = {0};
            int k = 0;
            while (flag1/2!=0) {
                flag[k++] = flag1 % 2;
                flag1 = flag1 / 2;
            }
            if(flag1 == 1)
            flag[k] = 1;
            for (int j = 3; j>=0; j--) {
                Encryption_Pro[n].boxOf_S[sum++] = flag[j];
                
            }
            
        }
    }
    void IPR_Operation(int result[]){
        int temp[64] = {};
        for (int i = 0;i<32 ; i++) {
            temp[i] = Encryption_Pro[16].R[i];
            temp[32+i] = Encryption_Pro[16].L[i];
        }
        for (int i = 0 ; i<64; i++) {
            result[i] = temp[IPR_Table[i]-1];
        }
    }
    void print(int flag){
        for (int i = 1; i < 17 ; i++) {
            printf("\nN = %d\n",i);
            printf("选择运算:");
            for (int j = 0; j<48; j++) {
                if(j%8 == 0 && j) printf(" ");
                printf("%d",Encryption_Pro[i].select_Operation[j]);
            }
            printf("\n子密钥加:");
            for (int j = 0; j<48; j++) {
                if(j%8 == 0 && j) printf(" ");
                printf("%d",Encryption_Pro[i].secretKey_Operation[j]);
            }
            printf("\nS盒:");
            for (int j = 0; j<32; j++) {
                if(j%8 == 0 && j) printf(" ");
                printf("%d",Encryption_Pro[i].boxOf_S[j]);
            }
            printf("\nL:");
            for (int j = 0; j<32; j++) {
                if(j%8 == 0 && j) printf(" ");
                printf("%d",Encryption_Pro[i].L[j]);
            }
            printf("\nR:");
            for (int j = 0; j<32; j++) {
                if(j%8 == 0 && j) printf(" ");
                printf("%d",Encryption_Pro[i].R[j]);
            }
            printf("\n");
        }
        printf("\n");
        if(flag == 0)
            cout<<"the result of secret text: "<<endl;
        else
            cout<<"the result of plain text: "<<endl;
        for (int i = 0; i<64; i++) {
            if (i%8 == 0 && i != 0) printf(" ");
            printf("%d",result_Secret[i]);
        }
        printf("\n");
    }
    void Pri_ChangeToByte(int secretKey[]){
        char temp[8] = {};
        int k = 0;
        for (int i = 0; i<64; i+=8) {
            int sum = 0;
            for (int j = i; j<i+8; j++) {
                sum += secretKey[j] * pow(2,7-j%8);
            }
            temp[k++] = sum;
        }
        cout<<"the plaintext of 8 byte is :"<<endl;
        for (int i = 0; i<8; i++) {
            printf("%c",temp[i]);
        }
        printf("\n");
    }
    
    
    展开全文
  • 主要介绍了python实现DES加密解密方法,以实例形式较为详细的分析了基于Python实现的DES加密与解密技巧,需要的朋友可以参考下
  • des加密解密源代码

    2018-11-19 19:24:47
    DES加密解密过程,C++实现
  • C语言实现DES加密解密算法.txtincludeint asciim8,m_1616,m64,asciik8,k_1616,k64,m_ip64,l32,r32,k_pc156,c28,d28,cd56,k_pc248,re48,sh32,tempr32,m064,m0064,res8;int type;int ip6458,50,42,34,26,18,10,2,60,52...
  • Des加密解密C语言实现

    千次阅读 2022-03-22 15:04:30
    它是由IBM公司研制的一种对称密码算法,对称性是指它使用同一个秘钥来加密解密数据,与之相对应的RSA加密算法则是一种非对称密码算法Des加密需要双方事先共同拟定一个秘钥,不对第三方公开。   Des还是一种...
  • DES算法(基于C语言,加密解密代码)DES算法(基于C语言,加密解密代码)/* Note:Your choice is C IDE */#include "stdio.h"#include "string.h"#define uchar unsigned char/******************************************...
  • 它的出现主要是为了取代DES加密算法的,因为我们都知道DES算法的密钥长度是56Bit,因此算法的理论安全强度是2的56次方。 AES密码与分组密码Rijndael基本上完全一致,Rijndael分组大小和密钥大小都可以为128位、192...
  • C语言实现DES加密解密

    万次阅读 多人点赞 2019-01-03 21:00:58
    每16个16进制数加密一次。如果不够16个,就补0;  再将密文转换为2进制,每个字母取二进制的前4位。存完后一个64位。再将这个64位二进制数字通过pc-1表映射,变成56位二进制数字。C0等于前28位,D0等于后28位。...
  • C语言实现DES解密算法

    千次阅读 2021-11-19 19:38:11
    C语言实现DES解密算法DES解密 DES解密 #include <stdio.h> #include <stdlib.h> #include <string.h> /*-------------------------------------------------------------------------------...
  • C语言版本的DES加密解密算法,代码!(DEV C++编译通过) 纯粹C语言写的,我在DEV C++上编译运行过. 最近一个多星期搞加密解密发现网上版本忒多,但C的少而且不全,所以现在想到贡献出来,希望给大家帮助!
  • 3des加密算法C语言实现

    热门讨论 2013-10-25 18:10:14
    3DES加密算法C语言实现代码,很好很实用.
  • 1 实验一 1实验题目 利用C/C++编程实现DES加密算法或MD5加密算法我选择的是用 C++语言实现 DES的加密算法 2 实验目的 通过编码实现DES算法或MD5算法深入掌握算法的加密原理理解其 实际应用 价值同时要求用C/C++语言...
  • C语言DES加密解密代码

    千次阅读 2021-04-26 17:11:26
    原理分析:C语言实现DEA加密解密详解 #include <stdio.h> #include <stdlib.h> #include <string.h> //密钥 //64位变56位密钥置换表 int pc_1[56]={ 57,49,41,33,25,17,9, 1,58,50,42,34,26,18...
  • 已编译通过能直接运行,可实现DES加密解密。zip内有函数调用大概流程图,较为简单好懂的C语言实现方法。
  • 3DES加密解密算法, 用C语言实现的代码实例 。// printf("Original data: %s\n", data); des(data, key1, len); //产生密钥,并调整数组byte,输出密文。 /*---再解次密---*/ printf("Please input a key2:\n...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,103
精华内容 841
关键字:

c语言编码des密码算法加密解密