DES加密算法C 实现

合集下载

DES算法的c++实现

DES算法的c++实现

DES算法的c++实现⽤数组存的位,改天⽤unsigned int重写下。

依然不负责填充。

#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盒三维数组// S114, 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,// S215, 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,// S310, 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,// S47, 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,// S52, 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,// S612, 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,// S74, 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,// S813, 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转换为INTstatic 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转换为CHARstatic 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,左右分别32static 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->48static 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];}};//逆IPstatic 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_2static 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->48Xor(temp,subkey,len);S(temp,temp_1,S_Box);//48->32P(temp_1,output,P_Table);//位数不变};//秘钥循环左移static void RotateL(const int input[28],int output[28], int leftCount){int i;int len=28;//因为不是位运算,所以可以不⽤unsignedfor(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];//Ld[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 swapr[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");return0;}。

加密算法 c语言

加密算法 c语言

加密算法 c语言C语言是一种广泛应用于计算机科学领域的编程语言,它具有高效、灵活、可靠的特点。

在密码学中,加密算法是一种用于保护信息安全的重要工具。

本文将介绍一些常见的加密算法和在C语言中的实现。

一、对称加密算法对称加密算法是一种使用相同的密钥进行加密和解密的算法。

其中,最常见的对称加密算法是DES(Data Encryption Standard)和AES(Advanced Encryption Standard)。

1. DES算法DES算法是一种将64位明文加密为64位密文的块加密算法。

它使用56位的密钥和一系列的置换、替换和移位操作来进行加密。

C语言中可以使用openssl库中的函数来实现DES算法的加密和解密。

2. AES算法AES算法是一种使用128位、192位或256位密钥进行加密和解密的块加密算法。

它使用一系列的置换、替换和线性变换操作来进行加密。

C语言中可以使用openssl库中的函数来实现AES算法的加密和解密。

二、非对称加密算法非对称加密算法是一种使用不同的密钥进行加密和解密的算法。

其中,最常见的非对称加密算法是RSA(Rivest-Shamir-Adleman)算法。

1. RSA算法RSA算法是一种基于数论的非对称加密算法。

它使用一对公钥和私钥来进行加密和解密。

C语言中可以使用openssl库中的函数来实现RSA算法的加密和解密。

三、散列函数散列函数是一种将任意长度的输入映射为固定长度输出的算法。

其中,最常见的散列函数是MD5(Message Digest Algorithm 5)和SHA(Secure Hash Algorithm)系列算法。

1. MD5算法MD5算法是一种广泛使用的散列函数,它将任意长度的输入映射为128位的输出。

C语言中可以使用openssl库中的函数来实现MD5算法。

2. SHA算法SHA算法是一系列散列函数,其中最常见的是SHA-1、SHA-256和SHA-512。

DES加密算法 C++版

DES加密算法 C++版

/*** Des加密算法初步完成版* 使用基础函数实现** @version 0.9* @author alexWu* @电子邮箱:alexthinking(at)* @新浪微博:/vikingalex* @完成日期:2011-10-25**/#include <cstdlib>#include <iostream>using namespace std;//轮密钥,由轮密钥生成器getKeys(key)获得并赋值int keys[16][48];//密匙置换选择1表,调用:getKeysint keyTable11[4][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}};int keyTable12[4][7] = {{63, 55, 47, 39, 31, 33, 15},{7, 62, 54, 46, 38, 30, 22},{14, 6, 61, 53, 45, 37, 29},{21, 13, 5, 28, 20, 12, 4}};//密匙置换选择2表,调用:getKeysint keyTable2[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}};//明文初始置换,调用:encryptint displaceTable[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}};//明文逆初始置换,调用:encryptint antiDisplaceTable[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,在F变换中调用:fTrans()int expandTable[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}};//S盒压缩,调用:sBoxTransint sBox[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} }};//置换变换P,调用:fTransint pTable[8][4] = {{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}};//将16进制字符串转换为二进制整形数组void HexToBin(char content[], int intArr[]) {for (int i = 0; i < 16; i++) {switch (content[i]) {case '0': intArr[i*4]=0; intArr[i*4+1]=0; intArr[i*4+2]=0; intArr[i*4+3]=0; break;case '1': intArr[i*4]=0; intArr[i*4+1]=0; intArr[i*4+2]=0; intArr[i*4+3]=1; break;case '2': intArr[i*4]=0; intArr[i*4+1]=0; intArr[i*4+2]=1; intArr[i*4+3]=0; break;case '3': intArr[i*4]=0; intArr[i*4+1]=0; intArr[i*4+2]=1; intArr[i*4+3]=1; break;case '4': intArr[i*4]=0; intArr[i*4+1]=1; intArr[i*4+2]=0; intArr[i*4+3]=0; break;case '5': intArr[i*4]=0; intArr[i*4+1]=1; intArr[i*4+2]=0; intArr[i*4+3]=1; break;case '6': intArr[i*4]=0; intArr[i*4+1]=1; intArr[i*4+2]=1; intArr[i*4+3]=0; break;case '7': intArr[i*4]=0; intArr[i*4+1]=1; intArr[i*4+2]=1; intArr[i*4+3]=1; break;case '8': intArr[i*4]=1; intArr[i*4+1]=0; intArr[i*4+2]=0; intArr[i*4+3]=0; break;case '9': intArr[i*4]=1; intArr[i*4+1]=0; intArr[i*4+2]=0; intArr[i*4+3]=1; break;case 'A': intArr[i*4]=1; intArr[i*4+1]=0; intArr[i*4+2]=1; intArr[i*4+3]=0; break;case 'B': intArr[i*4]=1; intArr[i*4+1]=0; intArr[i*4+2]=1; intArr[i*4+3]=1; break;case 'C': intArr[i*4]=1; intArr[i*4+1]=1; intArr[i*4+2]=0; intArr[i*4+3]=0; break;case 'D': intArr[i*4]=1; intArr[i*4+1]=1; intArr[i*4+2]=0; intArr[i*4+3]=1; break;case 'E': intArr[i*4]=1; intArr[i*4+1]=1; intArr[i*4+2]=1; intArr[i*4+3]=0; break;case 'F': intArr[i*4]=1; intArr[i*4+1]=1; intArr[i*4+2]=1; intArr[i*4+3]=1; break;}}}//将二进制整形数组转换为16进制字符串void BinToHex(int intArr[], char content[], int hexLen) {int tep;for (int i = 0; i < hexLen; i++) {tep = intArr[i*4]*8 + intArr[i*4+1]*4 + intArr[i*4+2]*2 + intArr[i*4+3];switch (tep) {case 0: content[i]='0'; break;case 1: content[i]='1'; break;case 2: content[i]='2'; break;case 3: content[i]='3'; break;case 4: content[i]='4'; break;case 5: content[i]='5'; break;case 6: content[i]='6'; break;case 7: content[i]='7'; break;case 8: content[i]='8'; break;case 9: content[i]='9'; break;case 10: content[i]='A'; break;case 11: content[i]='B'; break;case 12: content[i]='C'; break;case 13: content[i]='D'; break;case 14: content[i]='E'; break;case 15: content[i]='F'; break;}}if (hexLen < strlen(content)) {for (int i = hexLen; i < strlen(content); i++) {content[i]=' ';}}}//将密钥中C和D合并void plusArray(int c[], int d[], int result[], int len) {for (int i = 0; i < len; i++) {result[i] = c[i];}for (int i = 0; i < len; i++) {result[i + len] = d[i];}}//密钥置换选择1void keyTableTrans1(int binArr[64], int resultArr[28], int table[4][7]){ int count = 0;for (int i = 0; i < 4; i++) {for (int j = 0; j < 7; j++) {resultArr[count++] = binArr[table[i][j]-1];}}}//密钥置换选择2void keyTableTrans2(int binArr[56], int resultArr[16][48], int table[8][6], int index){ int count = 0;for (int i = 0; i < 8; i++) {for (int j = 0; j < 6; j++) {resultArr[index][count++] = binArr[table[i][j]-1];}}}//循环左移void leftMove(int count, int arr[]) {int arrLen = 28;int moveTable[16] = {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1};if (moveTable[count] == 1) {int tep0 = arr[0];for (int i = 0; i < arrLen - 1; i++) {arr[i] = arr[i+1];}arr[arrLen-1] = tep0;} else {int tep0 = arr[0];int tep1 = arr[1];for (int i = 0; i < arrLen - 2; i++) {arr[i] = arr[i+2];}arr[arrLen-2] = tep0;arr[arrLen-1] = tep1;}}//获取轮密钥void getKeys(char key[]){cout<<"密钥:"<<key<<endl;int keyIntArr[64], C[28], D[28];//将16进制字符串转换为二进制整形数组HexToBin(key, keyIntArr);//依次输出64位的二进制数组密钥//for (int i = 0; i < 64; i++) {// cout<<keyIntArr[i];//}//cout<<endl;//密钥置换选择1keyTableTrans1(keyIntArr, C, keyTable11);keyTableTrans1(keyIntArr, D, keyTable12);int tepKeyArr[56];//密钥C和D合并的暂存数组int tepKeyRstArr[48];//置换选择2后的48位数组char keysStr[12];//密钥转换的16进制字符串for (int i = 0; i < 16; i++) {leftMove(i, C);leftMove(i, D);//密钥C和D合并plusArray(C, D, tepKeyArr, 28);keyTableTrans2(tepKeyArr, keys, keyTable2, i);//依次输出置换选择2后的48位的二进制数组密钥//for (int j = 0; j < 48; j++) {// cout<<keys[i][j];//}//cout<<endl;//将二维数组keys的行key[i]赋给一维数组tepKeyRstArr//以便转换为16进制字符串for (int j = 0; j < 48; j++) {tepKeyRstArr[j] = keys[i][j];}BinToHex(tepKeyRstArr, keysStr, 12);cout<<"K"<<i+1<<" : "<<keysStr<<endl;}}//明文初始置换void plaintextTableTrans(int binArr[64], int table[8][8]){int tepBinary[64];int count = 0;for (int i = 0; i < 8; i++) {for (int j = 0; j < 8; j++) {tepBinary[count++] = binArr[table[i][j]-1];}}memcpy(binArr, tepBinary, sizeof(int) * 64);}//扩展运算Evoid expandTableTrans(int binArr[64], int resultArr[48], int table[8][6]){int count = 0;for (int i = 0; i < 8; i++) {for (int j = 0; j < 6; j++) {resultArr[count++] = binArr[table[i][j]-1];}}}//置换运算Pvoid pTableTrans(int binArr[32], int table[8][4]){int tepBinary[32];int count = 0;for (int i = 0; i < 8; i++) {for (int j = 0; j < 4; j++) {tepBinary[count++] = binArr[table[i][j]-1];}}memcpy(binArr, tepBinary, sizeof(int) * 32);}//复制数组void arrCopy(int sourceArray[], int result[], int startIndex) { //已知要复制数组长度为32for (int i = 0; i < 32; i++) {result[i] = sourceArray[startIndex + i];}}//数组每个元素异或运算void arrayXOR(int array1[], int array2[], int len) {for (int i = 0; i <len ; i++) {array1[i] = array1[i] ^ array2[i];}}//将S盒中取出的1-15的十进制数字转换为2进制4位整型数组void DecToBin(int intArr4[], int result) {intArr4[0] = result/8;intArr4[1] = (result%8)/4;intArr4[2] = (result%8%4)/2;intArr4[3] = result%8%4%2;}//选择压缩变换,S盒代替void sBoxTrans(int resultArr[], int arr[]) {int result = 0;int intArr4[4];int j = 0;for (int i = 0; i < 8; i++, j = i*6) {//获取S盒中对应的数据result = sBox[i][arr[j]*2 + arr[j+5]][arr[j+1]*8 + arr[j+2]*4 + arr[j+3]*2 + arr[j+4]];//将S盒中取出的十进制数转化成二进制DecToBin(intArr4, result);for (int n = 0, m = i*4; n < 4; n++) {resultArr[m+n] = intArr4[n];;}}}//F变换void fTrans(int R[], int index) {//F变换中的扩展运算Eint tepR[48];expandTableTrans(R, tepR, expandTable);//将二维数组keys的行key[i]赋给一维数组tepKeyArrint key[48];for (int j = 0; j < 48; j++) {key[j] = keys[index][j];}//扩展运算的得到的tepR与轮密匙key进行异或运算arrayXOR(tepR, key, 48);//选择压缩变换,S盒代替int sBoxArr[32];sBoxTrans(sBoxArr, tepR);//置换运算PpTableTrans(sBoxArr, pTable);memcpy(R, sBoxArr, sizeof(int) * 32);}//迭代处理void loop(int arr[]) {int L[32],R[32];arrCopy(arr, L, 0);arrCopy(arr, R, 32);char LStr[9]=" ",RStr[9]=" ";//先定义好L和RBinToHex(L, LStr, 8);BinToHex(R, RStr, 8);cout<<"L0:"<<LStr<<endl;cout<<"R0:"<<RStr<<endl;int tep[32];//前15轮乘积变换for (int i = 0; i < 15; i++) {memcpy(tep, R, sizeof(int) * 32);fTrans(R, i);//F变换arrayXOR(R, L, 32);//异或运算,得到最后的Rmemcpy(L, tep, sizeof(int) * 32);BinToHex(L, LStr, 8);BinToHex(R, RStr, 8);cout<<"L"<<i+1<<":"<<LStr<<" ";cout<<"R"<<i+1<<":"<<RStr<<endl;}//最后一轮乘积变换memcpy(tep, R, sizeof(int) * 32);fTrans(R, 15);//F变换arrayXOR(L, R, 32);//异或运算,得到最后的Rmemcpy(R, tep, sizeof(int) * 32);BinToHex(L, LStr, 8);BinToHex(R, RStr, 8);cout<<"L16:"<<LStr<<" ";cout<<"R16:"<<RStr<<endl;plusArray(L, R, arr, 32);}//加密void encrypt(char plaintext[]) {int binary[64];//二进制整型明文数组//将16进制表示的字符串转换为二进制字符串HexToBin(plaintext, binary);//初始置换plaintextTableTrans(binary, displaceTable);//16轮乘积变换loop(binary);//逆初始置换plaintextTableTrans(binary, antiDisplaceTable);BinToHex(binary, plaintext, 16);cout<<"密文:"<<plaintext<<endl;}//主函数int main(){char test[17]= "123456ABCD132536";//测试所用明文cout<<"明文:"<<test<<endl; //输出明文getKeys("AABB09182736CCDD");//获取密钥encrypt(test);//加密system("PAUSE");return 0;}。

des算法c++实现--文档

des算法c++实现--文档

高级编程DES加密算法C++程序实现姓名:***学号:*********专业:电路与系统一、DES算法简要介绍DES算法为密码体制中的对称密码体制,又被成为美国数据加密标准,是1972年美国IBM公司研制的对称密码体制加密算法。

明文按64位进行分组, 密钥长64位,密钥事实上是56位参与DES运算(第8、16、24、32、40、48、56、64位是校验位,使得每个密钥都有奇数个1)分组后的明文组和56位的密钥按位替代或交换的方法形成密文组的加密方法。

DES加密算法特点:分组比较短、密钥太短、密码生命周期短、运算速度较慢。

DES工作的基本原理是,其入口参数有三个:key、data、mode。

key为加密解密使用的密钥,data为加密解密的数据,mode为其工作模式。

当模式为加密模式时,明文按照64位进行分组,形成明文组,key用于对数据加密,当模式为解密模式时,key用于对数据解密。

实际运用中,密钥只用到了64位中的56位,这样才具有高的安全性。

DES算法把64位的明文输入块变为64位的密文输出块,它所使用的密钥也是64位。

DES算法具有极高安全性,到目前为止,除了用穷举搜索法对DES算法进行攻击外,还没有发现更有效的办法。

而56位长的密钥的穷举空间为256,这意味着如果一台计算机的速度是每一秒种检测一百万个密钥,则它搜索完全部密钥就需要将近2285年的时间,可见,这是难以实现的,当然,随着科学技术的发展,DES算法加密的明文已经被高速计算机破解,但是DES目前仍然得到广泛的应用,在某些场合仍然发挥余热。

12二、C++实现简要介绍2.1 密钥生成 2.1.1 取得密钥从用户处取得一个64位(本文如未特指,均指二进制位))长的密码key ,在程序实现中,用一9位字符数组存放用户输入的八个字符,然后将字符数组转换成二进制形式存储在一长度为64的int 型数组当中。

程序流程图如图表1示。

去除64位密码中作为奇偶校验位的第8、16、24、32、40、48、56、64位,剩下的56位作为有效输入密钥。

DES算法的C语言实现

DES算法的C语言实现

DES算法的C语⾔实现利⽤C语⾔实现DES算法,分组密码原理过程很简单,但是在写的过程中检查了好久才发现错误原因,主要有两点:1.在加密过程16轮迭代过程中,最后⼀轮迭代运算后的结果并没有进⾏交换,即C=IP-1(R16,L16),这样做的⽬的是为了加密解密使⽤同⼀个算法2.在S盒的过程中,移位后应该加括号,否则+的优先级⾼于<<,会出错,下⾯是算法源码:1 #include "des.h"2 #include <stdio.h>3 #include <stdlib.h>45const unsigned char IP_table[64] = {658, 50, 42, 34, 26, 18, 10, 2,760, 52, 44, 36, 28, 20, 12, 4,862, 54, 46, 38, 30, 22, 14, 6,964, 56, 48, 40, 32, 24, 16, 8,1057, 49, 41, 33, 25, 17, 9, 1,1159, 51, 43, 35, 27, 19, 11, 3,1261, 53, 45, 37, 29, 21, 13, 5,1363, 55, 47, 39, 31, 23, 15, 714 };1516const unsigned char IPR_table[64] = {1740, 8, 48, 16, 56, 24, 64, 32,1839, 7, 47, 15, 55, 23, 63, 31,1938, 6, 46, 14, 54, 22, 62, 30,2037, 5, 45, 13, 53, 21, 61, 29,2136, 4, 44, 12, 52, 20, 60, 28,2235, 3, 43, 11, 51, 19, 59, 27,2334, 2, 42, 10, 50, 18, 58, 26,2433, 1, 41, 9, 49, 17, 57, 2525 };2627const unsigned char E_table[48] = {2832, 1, 2, 3, 4, 5,294, 5, 6, 7, 8, 9,308, 9, 10, 11, 12, 13,3112, 13, 14, 15, 16, 17,3216, 17, 18, 19, 20, 21,3320, 21, 22, 23, 24, 25,3424, 25, 26, 27, 28, 29,3528, 29, 30, 31, 32, 136 };3738const unsigned char P_table[32] = {3916, 7, 20, 21, 29, 12, 28, 17,401, 15, 23, 26, 5, 18, 31, 10,412, 8, 24, 14, 32, 27, 3, 9,4219, 13, 30, 6, 22, 11, 4, 2543 };4445const unsigned char PC1_table[56] = {4657, 49, 41, 33, 25, 17, 9,471, 58, 50, 42, 34, 26, 18,4810, 2, 59, 51, 43, 35, 27,4919, 11, 3, 60, 52, 44, 36,5063, 55, 47, 39, 31, 23, 15,517, 62, 54, 46, 38, 30, 22,5214, 6, 61, 53, 45, 37, 29,5321, 13, 5, 28, 20, 12, 454 };5556const unsigned char LOOP_table[16] = {571, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 158 };5960const unsigned char PC2_table[48] = {6114, 17, 11, 24, 1, 5,623, 28, 15, 6, 21, 10,6323, 19, 12, 4, 26, 8,6416, 7, 27, 20, 13, 2,6541, 52, 31, 37, 47, 55,6630, 40, 51, 45, 33, 48,6744, 49, 39, 56, 34, 53,6846, 42, 50, 36, 29, 3269 };7071const unsigned char sbox[8][4][16] = {72// S17314, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,740, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,754, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,7615, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13,77//S27815, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,793, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,800, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,8113, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9,82//S38310, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,8413, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,8513, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,861, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12,87//S4887, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,8913, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,9010, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,913, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14,92//S5932, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,9414, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,954, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,9611, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3,97//S69812, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,9910, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,1009, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,1014, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13,102//S71034, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,10413, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,1051, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,1066, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12,107//S810813, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,1091, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,1107, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,1112, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11112 };113114void ByteToBit(unsigned char* out, const unsigned char* in, const int bits){115for(int i=0;i<bits;i++)116out[i]=(in[i/8]>>(7-i%8))&1;117 }118119void BitToByte(unsigned char* out, const unsigned char* in, const int bits){120 memset(out, 0, (bits + 7) / 8);121for(int i=0;i<bits;i++)122out[i/8]|=in[i]<<(7-i%8);123 }124125void Transform(unsigned char* out,const unsigned char* in, const unsigned char* table, const int len){ 126 unsigned char tmp[64] = {0};127for (int i = 0; i < len; i++)128 tmp[i] = in[table[i] - 1];129 memcpy(out, tmp, len);130 }131132void RotateL(unsigned char* in, const int len, int loop){133static unsigned char tmp[64];134 memcpy(tmp, in, len);135 memcpy(in, in + loop, len - loop);136 memcpy(in + len - loop, tmp, loop);137 }138139static unsigned char subKey[16][48] = { 0 };140void setKey(const unsigned char* in){141char key[64] = { 0 };142 ByteToBit(key, in, 64);143char temp[56]={0};144 Transform(temp, key, PC1_table, 56);145for(int i=0;i<16;i++){146 RotateL(temp, 28, LOOP_table[i]);147 RotateL(temp + 28, 28, LOOP_table[i]);148 Transform(subKey[i], temp, PC2_table, 48);149 }150 }151152void xor(unsigned char* in1,const unsigned char* in2,int len){153for(int i=0;i<len;i++)154 in1[i]^=in2[i];155 }156157void sbox_exchange(unsigned char* out,const unsigned char* in){158char row, column;159for (int i = 0; i < 8; i++){160char num = 0;161 row = (in[6 * i]<<1)+ in[6 * i + 5];162 column = (in[6 * i + 1] << 3) + (in[6 * i + 2] << 2) + (in[6 * i + 3] << 1) + in[6 * i + 4]; 163 num = sbox[i][row][column];164for (int j = 0; j < 4; j++)165 {166out[4 * i + j] = (num >> (3 - j)) & 1;167 }168 }169 }170171void F_func(unsigned char* out,const unsigned char* in,unsigned char* subKey){172 unsigned char temp[48]={0};173 unsigned char res[32]={0};174 Transform(temp, in, E_table, 48);175 xor(temp,subKey,48);176 sbox_exchange(res,temp);177 Transform(out, res, P_table, 32);178 }179180void encryptDES(unsigned char* out,const unsigned char* in, const unsigned char* key){ 181 unsigned char input[64] = { 0 };182 unsigned char output[64] = { 0 };183 unsigned char tmp[64] = { 0 };184 ByteToBit(input, in, 64);185 Transform(tmp, input, IP_table, 64);186char* Li = &tmp[0], *Ri = &tmp[32];187 setKey(key);188for(int i=0;i<16;i++){189char temp[32]={0};190 memcpy(temp,Ri,32);191 F_func(Ri, Ri,subKey[i]);192 xor(Ri, Li, 32);193 memcpy(Li,temp,32);194 }195 RotateL(tmp, 64, 32);//the input is LR,output is RL196 Transform(output, tmp, IPR_table, 64);197 BitToByte(out, output,64);198 }199200void decryptDES(unsigned char* out,const unsigned char* in, const unsigned char* key){ 201 unsigned char input[64] = { 0 };202 unsigned char output[64] = { 0 };203 unsigned char tmp[64] = { 0 };204 ByteToBit(input, in, 64);205 Transform(tmp, input, IP_table, 64);206char* Li = &tmp[0], *Ri = &tmp[32];207 setKey(key);208 RotateL(tmp, 64, 32);209for (int i = 0; i < 16; i++){210char temp[32] = { 0 };211 memcpy(temp, Li, 32);212 F_func(Li, Li,subKey[15 - i]);213 xor(Li, Ri, 32);214 memcpy(Ri, temp, 32);215 }216 Transform(output, tmp, IPR_table, 64);217 BitToByte(out, output, 64);218 }。

用c语言实现des算法

用c语言实现des算法

用c语言实现des算法由于DES算法被广泛应用于加密和数据安全方面,因此在计算机科学领域,了解和实现DES算法是非常重要的。

C语言是一种强大的编程语言,其通用性和高效性使其成为实现DES算法的理想选择。

以下是使用C语言实现DES算法的步骤和方法:1.将明文和密钥转换为二进制格式在DES算法中,明文和密钥必须先转换为二进制格式才能进行加密或解密操作。

可以使用一个字符串数组来存储明文和密钥,然后使用C 语言的位运算符将每个字符转换为二进制格式。

2.对明文进行初始置换DES算法的第一步是对明文进行初始置换。

可以使用一个int型数据来存储初始置换后的结果。

3.密钥生成使用密钥生成算法来生成16个48位的子密钥。

可以使用一个二维数组来存储每个子密钥。

4.将初始置换后的明文分为左右两个部分将初始置换后的明文分为左右两个部分,每个部分32位。

5.进行16轮迭代在每轮迭代中,右半部分32位的明文和48位的子密钥进行异或运算,然后使用S盒置换和P盒置换来处理数据。

最后将结果与左半部分32位的明文异或,以更新下一轮迭代所需的数据。

6.合并左右两个部分在进行最后一轮迭代后,将左右两个部分合并成一段64位的二进制数据。

7.进行最后的逆置换使用逆置换来处理上一步生成的64位二进制数据,以生成最终的密文。

实现DES算法需要一定的数学知识和编程技能,因此建议有一定编程基础的人才尝试实现此算法。

列表:1.使用C语言实现DES算法步骤2.将明文和密钥转换为二进制格式的方法3.对明文进行初始置换的具体过程4.密钥生成算法的原理和实现方法5.如何将初始置换后的明文分为左右两个部分6.DES算法16轮迭代的详细过程7.如何合并左右两个部分的数据8.DES算法中的最后一步逆置换的作用和过程9.DES算法的应用场景和重要性10.如何使用C语言实现DES算法的具体步骤和技巧。

DES对称加密算法详解和c++代码实现(带样例和详细的中间数据)

DES对称加密算法详解和c++代码实现(带样例和详细的中间数据)

DES对称加密算法详解和c++代码实现(带样例和详细的中间数据)特点:1.DES是对称性加密算法,即加密和解密是对称的,⽤的是同⼀个密钥2.DES只处理⼆进制数据,所以需要将明⽂转换成为2进制数据3.DES每次处理64位的数据,所以应该将明⽂切割成64位的分组,当最后⼀组数据不⾜64位的时候,⾼位补04.DES使⽤64位的密钥,但因为密钥中的每8位会被忽略,所以有效的密钥长度是56位,从⽽产⽣16个48位的⼦密钥(变换过程后⾯会说明)5.每64位数据⼀个块,是DES的永恒组织⽅式具体样例分析:(仅以⼀组64位数据为例分析加密过程)明⽂M是:8787878787878787密钥K是:0E329232EA6D0D73上⾯的信息都是16进制的,转换为2进制明⽂M是:0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111密钥K是:00010011 00110100 01010111 01111001 10011011 10111100 11011111 11110001第⼀步:根据密钥⽣成16个⼦密钥1.根据密钥初始置换表将64位的密钥转化为58位的密钥57 49 41 33 25 17 91 58 50 42 34 26 1810 2 59 51 43 35 2719 11 3 60 52 44 3663 55 47 39 31 23 157 62 54 46 38 30 2214 6 61 53 45 37 2921 13 5 28 20 12 4由于上表中第⼀个元素为57,这将使原秘钥的第57位变换为新秘钥K+的第1位。

同理,原秘钥的第49位变换为新秘钥的第2位……原秘钥的第4位变换为新秘钥的最后⼀位。

注意原秘钥中只有56位会进⼊新秘钥,上表也只有56个元素。

原密钥K:00010011 00110100 01010111 01111001 10011011 10111100 11011111 11110001新密钥K:1111000 0110011 0010101 0101111 0101010 1011001 1001111 00011112.将新密钥拆分成C0和D0,每组都有28位⽐如新密钥C0:1111000 0110011 0010101 0101111D0:0101010 1011001 1001111 00011113.根据密钥轮次左移表,左移特定的位数1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 161 12 2 2 2 2 2 1 2 2 2 2 2 2 1⽐如第⼀轮是左移1位,第⼆轮也是左移1位,第三轮是左移两位所以C1:1110000110011001010101011111D1:1010101011001100111100011110下⾯给出C1,D1到C16,D16的数据:C1 = 1110000110011001010101011111D1 = 1010101011001100111100011110C2 = 1100001100110010101010111111D2 = 0101010110011001111000111101C3 = 0000110011001010101011111111D3 = 0101011001100111100011110101C4 = 0011001100101010101111111100D4 = 0101100110011110001111010101C5 = 1100110010101010111111110000D5 = 0110011001111000111101010101C6 = 0011001010101011111111000011D6 = 1001100111100011110101010101C7 = 1100101010101111111100001100D7 = 0110011110001111010101010110C8 = 0010101010111111110000110011D8 = 1001111000111101010101011001C9 = 0101010101111111100001100110D9 = 0011110001111010101010110011C10 = 0101010111111110000110011001D10 = 1111000111101010101011001100C11 = 0101011111111000011001100101D11 = 1100011110101010101100110011C12 = 0101111111100001100110010101D12 = 0001111010101010110011001111C13 = 0111111110000110011001010101D13 = 0111101010101011001100111100C14 = 1111111000011001100101010101D14 = 1110101010101100110011110001C15 = 1111100001100110010101010111D15 = 1010101010110011001111000111C16 = 1111000011001100101010101111D16 = 0101010101100110011110001111需要记住的是:每⼀对Cn 和 Dn都是由前⼀对Cn-1 和 Dn-1移位⽽来!4.得到Cn,Dn后合并CnDn,然后根据密钥压缩置换表将56位密钥压缩成48位的⼦密钥密钥压缩置换表:14 17 11 24 1 53 28 15 6 21 1023 19 12 4 26 816 7 27 20 13 241 52 31 37 47 5530 40 51 45 33 4844 49 39 56 34 5346 42 50 36 29 32每对⼦秘钥有56位,但PC-2仅仅使⽤其中的48位。

DES加解密算法C语言源代码

DES加解密算法C语言源代码

DES加解密算法C语言源代码以下是一个实现DES加解密算法的C语言源代码,包含了加密和解密函数。

请注意,这个代码只是为了演示DES算法的工作原理,并不是一个完整的、安全的加密算法实现。

```c#include <stdio.h>#include <stdint.h>typedef structuint8_t key[8];uint8_t subkeys[16][6];} DESKey;void generateSubkeys(uint8_t* key, uint8_t subkeys[16][6]) //略过子密钥生成算法的具体实现//这里只是假设生成的子密钥都是随机的,实际生成过程要更复杂for (int i = 0; i < 16; i++)for (int j = 0; j < 6; j++)subkeys[i][j] = (i+j) % 256;}}void DES(uint8_t* input, uint8_t key[8], uint8_t* output, int encrypt)//略过DES加密算法的具体实现DESKey desKey;for (int i = 0; i < 8; i++)desKey.key[i] = key[i];}generateSubkeys(key, desKey.subkeys);//这里只是假设输入输出是8字节长,实际上可以支持任意长度//执行加解密操作if (encrypt)printf("Encrypting: ");} elseprintf("Decrypting: ");}for (int i = 0; i < 8; i++)output[i] = encrypt ? input[i] ^ desKey.subkeys[0][i%6] : input[i] ^ desKey.subkeys[15][i%6];printf("%02X ", output[i]);}printf("\n");int maiuint8_t input[8] = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0};uint8_t key[8] = {0xA1, 0xB2, 0xC3, 0xD4, 0xE5, 0xF6, 0x07,0x08};uint8_t output[8];DES(input, key, output, 1);DES(output, key, output, 0);return 0;```在这个代码中,`generateSubkeys` 函数用于生成 16 个子密钥,之后分别在加密和解密函数 `DES` 中使用。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

5、按 1 开始进行解密,流程与加密相同,中间过程省去,只给出最终结果:
7、实验总结
通过完成本实验, 我详细了解了 DES 算法的实现过程和工作原理, 相比较在课堂上学到 的理论知识,我认为通过实践后掌握的更加深刻。在课堂上我们学习 DES 算法,很多都是基 于理论上的知识,但并没有真正的使用过 DES,而通过编码实现 DES,我们更好地理解了该 怎么用 DES 去解决实际问题,这对我们以后的学习是很有帮助的,掌握了 DES 的算法实现 后,我们在以后写到相关程序时可以快速的将其利用,使其真正的为我们服务。
DES 加密算法的 C++实现
实验一
1、实验题目
利用 C/C++ 编程实现 DES 加密算法或 MD5 加密算法。我选择的是用 C++ 语言实现 DES 的加密算法。
2、实验目的
通过编码实现 DES 算法或 MD5 算法,深入掌握算法的加密原理,理解其实际应用 价值,同时要求用 C/C++语言实现该算法,让我们从底层开始熟悉该算法的实现过程
2, 4, 6, 8, 1, 3, 5, 7
//逆置换矩阵 int IP_ANTEX[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, 41, 10, 50, 18, 58, 26, 33, 1, 41, 9, 49, 17, 57, 25 }; //扩展矩阵 int EXTEND[48]= {
3、实验环境
操作系统:WIN7 旗舰版 开发工具:Visual Studio 2010 旗舰版 开发语言:C++
4、实验原理
DES 加密流程:
1
如上图所示为 DES 的加密流程,其中主要包含初始置换,压缩换位 1,压缩换位 2,扩 展置换,S 盒置换,异或运算、终结置换等过程。 初始置换是按照初始置换表将 64 位明文重新排列次序 扩展置换是将原 32 为数据扩展为 48 位数据,它主要由三个目的: 1、产生与子密钥相同的长度 2、提供更长的结果,使其在加密过程中可以被压缩 3、产生雪崩效应,使得输入的一位将影响两个替换 S 盒置换是 DES 算法中最核心的内容, 在 DES 中, 只有 S 盒置换是非线性的, 它比 DES 中其他任何一步都提供更好的安全性 终结置换与初始置换相对应, 它们都不影响 DES 的安全性, 主要目的是为了更容易将 明文与密文数据一字节大小放入 DES 的 f 算法中 DES 解密流程与加密流程基本相同,只不过在进行 16 轮迭代元算时,将子密钥生成的 K 的次序倒过来进行迭代运算
函数执行次序和调用关系关系如下:
3
6、实验结果
1、根据提示,输入任意 8 字节的原文,并将其转换为 64 为二进制明文:
2、将 64 为二进制明文进行初始置换:
3、将原 64 位明文分成左右两半,并对右半边进行扩展置换:
4
4 依次获得子密钥。 按上述流程完成 16 轮迭代运算后进行终结置换, 得到 64 位密文 (整 个过程设计数据过多,没有一一输出,只给出最终截图内容)
7
{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 DIREX[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 }; //左移移位表 int MOVELEFT[16]= { 1,1,2,2,2,2,2,2, 1,2,2,2,2,2,2,1 }; //压缩换位表 2 int CutEX[48]= { 14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10,
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, 1, 2 }; //S 盒 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} }, { {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} }, { {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清晰的认识后,编码过程中我将其分为几个关键部分分别进行编码, 最后将整个过程按顺序执行,即可完成 DES 的加密,代码的主要几个函数如下:
//Byte转为Bit ByteToBit(ElemType ch,ElemType bit[8]) //Bit转为Byte BitToByte(ElemType bit[8],ElemType &ch) //初始置换 InitialEX(ElemType Inorder[64],ElemType Disorder[64]) //终结置换 AntiEx(ElemType Disorder[64]) //扩展置换 ExpandEX(ElemType RightMsg[32],ElemType ExpandMsg[48]) //16轮迭代加密 MoveLeft(ElemType C[28],ElemType D[28],ElemType L0[32],ElemType R0[32])
//置换矩阵 int IP_EX[64]= { 58, 50, 42, 34, 26, 18, 10, 60, 52, 44, 36, 28, 20, 12, 62, 54, 46, 38, 30, 22, 14, 64, 56, 48, 40, 32, 24, 16, 57, 49, 41, 33, 25, 17, 9, 59, 51, 43, 35, 27, 19, 11, 61, 53, 45, 37, 29, 21, 13, 63, 55, 47, 39, 31, 23, 15, };
相关文档
最新文档