DES加密

1)DES的加密过程
明文64位->初始置换IP->16轮加密变换->逆初始置换IP-1->密文
a.初始置换IP
图为初始置换IP表
这里的初始IP置换表的意思为把64位明文按照表中的规则替换,比如第一行,把64位明文的第1位换为其58位,第2位换为50位,第3位换位42位…这表仔细观察有一定的规律,比如我们从右到左一列一列的分别读前4行,后4行。是不是就是2 4 6 8 10 12…和1 3 5 7 9 11…
b.16轮加密变换
16轮加密变换
看似很复杂,其实16轮的过程都是一样的。经过上面说的初始置换IP,接下来就是要把64位分为L0和R0各32位。然后算出f(R0,k1),其结果与L0异或作为R1.而L1直接是和R0相等的。
后面都一样: Li=Ri-1
Ri=Li-1异或f(Ri-1,ki)
i=1,2,3,…16,
这时我们就会问那K1~K16从哪来,加密函数f()怎么计算,这些问题我在后面会继续写的。
c.初始逆置换IP-1
这里写图片描述
方法同初始置换IP。
b1.密钥生成
这里写图片描述
是不是一下子就能看明白,这里的PC-1为选择置换,可以去掉奇偶校验位。PC-2也是选择置换,它是用于从Ci和Di中选取48位作为密钥Ki。C0和D0是把密钥中实际的56位分成左右28位,LSi是表示对Ci-1和Di-1进行循环左移变换,其中LS1,LS2,LS9,LS16是循环左移1位,其余为2位。
选择置换PC-1
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
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
b2.加密函数f()
这里写图片描述
这里的E是把32比特(即上面所提到的64比特分为俩个32比特。)的输入扩展为48比特。将E置换后的结果与48位的Ki异或的结果平均分为8组B1,B2…B8,每组Bi用Si盒处理。这样你会发现进去的是48位,出来的是32位。因为P为32位置换函数,它的输入为32位。把Bi{x1,x2,x3…x6}(48比特平均分为8组,每组就是6比特)中的x1x6和x2x3x4x5分别作为Si盒的行和列(比如x1x2x3…x6=101011,则x1x6=11把它转化为十进制为3。x2x3x4x5=0101转换为十进制为5,所以为3行5列,但是要注意Si盒的行列从0开始算起),找到这个十进制数,把它转化为4位二进制。这4位就是输出。
扩展变换E
这里写图片描述
这个也是有规律的把第一列和最后一列去掉看看。
S盒
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 ,
p置换
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

c++demo:
 

#include<stdio.h>
#include<string.h>
int IP_Table[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 E_Table[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 P_Table[32] = {                                             //  P 盒
    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};
int IPR_Table[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 PC1_Table[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 PC2_Table[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_Box[8][4][16]={                     //8个S盒   三维数组
    // 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
};

//把CHAR转换为INT
static void CharToBit(const char input[],int output[],int bits){
    int i,j;
    for(j=0;j<8;j++){
        for(i=0;i<8;i++){
            output[8*j+7-i]=(input[j]>>i)&1;
        }
    }
};

//把INT转换为CHAR
static void BitToChar(const int intput[],char output[],int bits){
    int i,j;
    for(j=0;j<8;j++){
        for(i=0;i<8;i++){
            output[j]=output[j]*2+intput[i+8*j];
        }
    }
};
//异或操作
static void Xor(int *INA,int *INB,int len){
    int i;
    for(i=0;i<len;i++){
        *(INA+i)=*(INA+i)^*(INB+i);
    }
};
//初始IP置换,64->64,左右分别32
static void IP(const int input[64],int output[64],int table[64]){
    int i;
    for(i=0;i<64;i++){
        output[i]=input[table[i]-1];//减1操作不可少!!
    }
};
//E扩展32->48
static void E(const int input[32],int output[48],int table[48]){
    int i;
    for(i=0;i<48;i++){
        output[i]=input[table[i]-1];
    }
};
//P置换,
static void P(const int input[32],int output[32],int table[32]){
    int i;
    for(i=0;i<32;i++){
        output[i]=input[table[i]-1];
    }
};
//逆IP
static  void IP_In(const int input[64],int output[64],int table[64]){
    int i;
    for(i=0;i<64;i++){
        output[i]=input[table[i]-1];
    }
};
//PC_1,用于密钥置换
static void PC_1(const int input[64],int output[56],int table[56]){
    int i;
    for(i=0;i<56;i++){
        output[i]=input[table[i]-1];
    }
};
//PC_2
static void PC_2(const int input[56],int output[48],int table[48]){
    int i;
    for(i=0;i<48;i++){
        output[i]=input[table[i]-1];
    }
};
//S盒压缩
static void S(const int input[48],int output[32],int table[8][4][16]){
    int i=0;
    int j=0;
    int INT[8];
    for(;i<48;i+=6){
        INT[j]=table[j][(input[i]<<1)+(input[i+5])][(input[i+1]<<3)+(input[i+2]<<2)+(input[i+3]<<1)+(input[i+4])];
        j++;
    }
    for(j=0;j<8;j++){
        for(i=0;i<4;i++){
            output[4*j+3-i]=(INT[j]>>i)&1;
        }
    }
};


//完成DES算法轮变换,就是f函数的内部实现,就是一个异或而已
static void F_func(int input[32],int output[32], int subkey[48]){
    int len=48;
    int temp[48]={0};
    int temp_1[32]={0};
    E(input,temp,E_Table);//32->48
    Xor(temp,subkey,len);
    S(temp,temp_1,S_Box);//48->32
    P(temp_1,output,P_Table);//位数不变
};


//秘钥循环左移
static void RotateL(const int input[28],int output[28], int leftCount){
    int i;
    int len=28;//因为不是位运算,所以可以不用unsigned
    for(i=0;i<len;i++){
        output[i]=input[(i+leftCount)%len];
    }
};

//子密钥生成
static void subKey_fun(const int input[64],int Subkey[16][48]){//注意输入和输出的位数,int只存放01,密钥为18位16轮
    int loop=1,loop_2=2;
    int i,j;
    int c[28],d[28];
    int pc_1[56]={0};
    int pc_2[16][56]={0};
    int rotatel_c[16][28]={0};
    int rotatel_d[16][28]={0};
    PC_1(input,pc_1,PC1_Table);
    for(i=0;i<28;i++){
        c[i]=pc_1[i];//L
        d[i]=pc_1[i+28];//R
    }
    int leftCount=0;
    for(i=1;i<17;i++){
        if(i==1||i==2||i==9||i==16){//左移一位
            leftCount+=loop;
            RotateL(c,rotatel_c[i-1],leftCount);
            RotateL(d,rotatel_d[i-1],leftCount);
        }
        else{//左移两位
            leftCount += loop_2;
            RotateL(c,rotatel_c[i-1],leftCount);
            RotateL(d,rotatel_d[i-1],leftCount);
        }
    }
    for(i=0;i<16;i++){
        for(j=0;j<28;j++){
            pc_2[i][j]=rotatel_c[i][j];
            pc_2[i][j+28]=rotatel_d[i][j];
        }
    }
    for(i=0;i<16;i++){
        PC_2(pc_2[i],Subkey[i],PC2_Table);
    }
};


//加密实现
static void  DES_Efun(char input[8],char key_in[8],int output[64]){
    int Ip[64]={0};//存储初始置换后的矩阵
    int output_1[64]={0};
    int subkeys[16][48];
    int chartobit[64]={0};
    int key[64];
    int l[17][32],r[17][32];
    CharToBit(input,chartobit,8);//转换为64个二进制数
    IP(chartobit,Ip,IP_Table);//IP初始置换!
    CharToBit(key_in,key,8);
    subKey_fun(key,subkeys);
    for(int i=0;i<32;i++){
        l[0][i]=Ip[i];
        r[0][i]=Ip[32+i];
    }
    for(int j=1;j<16;j++){//前15轮的操作
        for(int k=0;k<32;k++){
            l[j][k]=r[j-1][k];
        }
        F_func(r[j-1],r[j],subkeys[j-1]);
        Xor(r[j],l[j-1],32);
    }
    int t=0;
    for(t=0;t<32;t++){//最后一轮的操作,合并了将l,r swap
        r[16][t]=r[15][t];
    }
    F_func(r[15],l[16],subkeys[15]);
    Xor(l[16],l[15],32);
    for(t=0;t<32;t++){
        output_1[t]=l[16][t];
        output_1[32+t]=r[16][t];
    }
    IP_In(output_1,output,IPR_Table);
};



//解密实现
static void  DES_Dfun(int input[64],char key_in[8],char output[8]){
    int Ip[64]={0};//存储初始置换后的矩阵
    int output_1[64]={0};
    int output_2[64]={0};
    int subkeys[16][48];
    //int chartobit[64]={0};
    int key[64];
    int l[17][32],r[17][32];
    IP(input,Ip,IP_Table);//IP初始置换
    CharToBit(key_in,key,8);
    subKey_fun(key,subkeys);
    for(int i=0;i<32;i++){
        l[0][i]=Ip[i];
        r[0][i]=Ip[32+i];
    }
    for(int j=1;j<16;j++){//前15轮的操作
        for(int k=0;k<32;k++){
            l[j][k]=r[j-1][k];
        }
        F_func(r[j-1],r[j],subkeys[16-j]);
        Xor(r[j],l[j-1],32);
    }
    int t=0;
    for(t=0;t<32;t++){//最后一轮的操作
        r[16][t]=r[15][t];
    }
    F_func(r[15],l[16],subkeys[0]);
    Xor(l[16],l[15],32);
    for(t=0;t<32;t++){
        output_1[t]=l[16][t];
        output_1[32+t]=r[16][t];
    }
    IP_In(output_1,output_2,IPR_Table);
    BitToChar(output_2,output,8);
};


int main(){
    int output[64]={0};
    char MIN[9]={0};
    char MI[9]={0};
    printf("请输入明文\n");
    gets(MIN);
    printf("请输入秘钥\n");
    gets(MI);
    DES_Efun(MIN,MI,output);
    printf("密文如下:\n");
    for(int i=0;i<64;i++){
        printf("%d",output[i]);
        if((i+1)%4==0)
            printf("\n");
    }
    printf("\n");
    printf("解密功能\n");
    DES_Dfun(output,MI,MIN);
    printf("明文如下:\n");
    for(int i=0;i<8;i++){
        printf("%c",MIN[i]);
    }
    printf("\n");
    return 0;
}

java实现:

import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;


public class DESHelper {
    /**
     * 加密解密接口
     * @param data      数据
     * @param password  加密解密密码 必须8位字节
     * @param flag      加密解密标志 0:加密 ,1:解密
     * @return
     */
    public static String doWork(String data, String password,int flag) {
        try {
            SecureRandom random = new SecureRandom();
            DESKeySpec desKey = new DESKeySpec(password.getBytes());
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
            SecretKey securekey = keyFactory.generateSecret(desKey);
            Cipher cipher = Cipher.getInstance("DES");
            // 
            if(flag == 0){
                BASE64Encoder base64encoder = new BASE64Encoder();
                cipher.init(Cipher.ENCRYPT_MODE, securekey, random);
                return base64encoder.encode(cipher.doFinal(data.getBytes("UTF-8")));
            }else{
                BASE64Decoder base64decoder = new BASE64Decoder();
                byte[] encodeByte = base64decoder.decodeBuffer(data);
                cipher.init(Cipher.DECRYPT_MODE, securekey, random);
                byte[] decoder = cipher.doFinal(encodeByte);
                return new String(decoder,"UTF-8");
            }
            
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    
    /**
     * test
     * @param args
     */
    public static void main(String[] args) {
        try {
            // 明文
            String str = "mobile:15810557051|type:0|content:你好";
            // 密码
            String password = "01010101";
            String desc = DESHelper.doWork(str, password,0);
            System.out.println("密文:" + desc);
            // 解密
            str = DESHelper.doWork(desc, password,1);
            System.out.println("明文:" +str);
        } catch (Exception e1) {
            e1.printStackTrace();
        }

    }
}

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值