C语言实现DES加密解密算法
DES加密解密纯C语言实现
#include<stdio.h>#include<stdlib.h>#include<string.h>void show1() //主界面{printf("\n\n\n\t\t*************** DES加密解密系统******************\n\n");printf("\t\t--------------------------------------------------\n");//printf("\t\t--------------------------------------------------\n");printf("\t\t**************************************************\n");printf("\t\t**\t\t\t\t\t\t**\n");printf("\t\t**\t\t\t\t\t\t**\n");printf("\t\t**\t\t\t1.加密\t\t\t**\n");printf("\t\t**\t\t\t\t\t\t**\n");printf("\t\t**\t\t\t2.解密\t\t\t**\n");printf("\t\t**\t\t\t\t\t\t**\n");printf("\t\t**\t\t\t3.退出\t\t\t**\n");printf("\t\t**\t\t\t\t\t\t**\n");printf("\t\t**\t\t\t\t\t\t**\n");printf("\t\t--------------------------------------------------\n");}void show2() //加密界面{printf("\n\n\n\t\t****************** DES加密**********************\n\n");printf("\t\t--------------------------------------------------\n");printf("\t\t**************************************************\n");printf("\t\t**\t\t\t\t\t\t**\n");printf("\t\t**\t请选择明文和密钥的输入方式:\t\t**\n");printf("\t\t**\t\t\t\t\t\t**\n");printf("\t\t**\t\t1.直接输入\t\t\t**\n");printf("\t\t**\t\t\t\t\t\t**\n");printf("\t\t**\t\t2.从文件读取\t\t\t**\n");printf("\t\t**\t\t\t\t\t\t**\n");printf("\t\t**\t\t3.退出\t\t\t\t**\n");printf("\t\t**\t\t\t\t\t\t**\n");printf("\t\t--------------------------------------------------\n");printf("\t\t\t选择:");}void reader(char str[30],char s[8]) //读取明文和密钥{FILE *fp;fp=fopen(str,"r");if(fp==NULL){printf("明文读取失败!\n");}else{fscanf(fp,"%s",s);}fclose(fp);}void To2Bin(char p[8],int b[64]) //将字节转换成二进制流{int i,k=0;for(i=0;i<8;i++){int j=0x80;for(;j;j>>=1){if(j&p[i]){b[k++]=1;}else{b[k++]=0;}}}}int IP_Table[64] = //初始置换(IP){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,56, 48, 40, 32, 24, 16, 8, 0,58, 50, 42, 34, 26, 18, 10, 2,60, 52, 44, 36, 28, 20, 12, 4,62, 54, 46, 38, 30, 22, 14, 6};int E_Table[] = { //扩展变换E31, 0, 1, 2, 3, 4,3, 4, 5, 6, 7, 8,7, 8, 9, 10, 11, 12,11, 12, 13, 14, 15, 16,15, 16, 17, 18, 19, 20,19, 20, 21, 22, 23, 24,23, 24, 25, 26, 27, 28,27, 28, 29, 30, 31, 0};int S_Box[8][4][16] = { //8个s盒{{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, 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 IP_1_Table[64] = //逆初始置换IP^-1 {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,32, 0, 40, 8, 48, 16, 56, 24};int P_Table[32] = //置换运算P{15,6,19,20,28,11,27,16,0,14,22,25,4,17,30,9,1,7,23,13,31,26,2,8,18,12,29,5,21,10,3,24};int PC_1[56] ={56,48,40,32,24,16,8, //密钥置换PC_10,57,49,41,33,25,17,9,1,58,50,42,34,26,18,10,2,59,51,43,35,62,54,46,38,30,22,14,6,61,53,45,37,29,21,13,5,60,52,44,36,28,20,12,4,27,19,11,3};int PC_2[48] = //密钥置换PC_2{13,16,10,23,0,4,2,27,14,5,20,9,22,18,11,3,25,7,15,6,26,19,12,1,40,51,30,36,46,54,29,39,50,44,32,47,43,48,38,55,33,52,45,41,49,35,28,31};void Replacement(int arry1[],int arry2[],int arry3[],int num) //置换函数(初始IP,逆初始IP,{int i,tmp;for(i=0;i<num;i++){tmp=arry2[i];arry3[i]=arry1[tmp];}}int move_times[16] = {1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1}; //对左移位的规定void lif_move(int arry1[],int arry2[],int n) //左移位实现函数{int i;for(i=0;i<28;i++){arry2[i]=arry1[(n+i)%28];}}int K[16][48]; //存放16轮子密钥int c[64]; //存放明文或密文int L[17][32],R[17][32]; //存放加密过程中左右部分void SubKey(int K0[64]) //子密钥产生函数{int i;int K1[56],K2[56];int C[17][28],D[17][28];Replacement(K0,PC_1,K1,56); //密钥置换PC_1for(i=0;i<28;i++) //将PC_1输出的56比特分为左右两部分{C[0][i]=K1[i];D[0][i]=K1[i+28];}i=0;while(i<16){int j;lif_move(C[i],C[i+1],move_times[i]);lif_move(D[i],D[i+1],move_times[i]);for(j=0;j<28;j++){K2[j]=C[i+1][j];K2[j+28]=D[i+1][j];}Replacement(K2,PC_2,K[i],48); //密钥置换PC_2i++;}/*printf("\n子密钥生成过程中,左边生成的值:");for(i=0;i<17;i++){int j;printf("\nC[%d]:",i);for(j=0;j<28;j++){if(j%7==0){printf(" ");}printf("%d",C[i][j]);}}printf("\n子密钥生成过程中,右边生成的值:");for(i=0;i<17;i++){int j;printf("\nD[%d]:",i);for(j=0;j<28;j++){if(j%7==0){printf(" ");}printf("%d",D[i][j]);}}*/}void S_compress(int arry[],int shc[]) //S盒压缩变换,其中数组shc存放经过s盒的结果{int h,l; //行,列int sha[8]; //存放经过s盒的十进制结果int i,j;int temp[4];for(i=0;i<8;i++) //s盒压缩变换{h=arry[(1+(i*6))-1]*2 + arry[(6+(i*6))-1];l =arry[(2+(i*6))-1]*8 + arry[(3+(i*6))-1]*4 + arry[(4+(i*6))-1]*2 + arry[(5+(i*6))-1];sha[i]=S_Box[i][h][l];}for(i=0;i<8;i++){for(j=3;j>=0;j--){sha[i]=sha[i]/2;}for(j=0;j<4;j++){shc[4*i+j]=temp[j];}}/*printf("\n第%d次s盒的输出:",m++);for(i=0;i<32;i++){if(i%8==0){printf(" ");}printf("%d",shc[i]);}*/}void To10(int a[], int b[],int n)//二进制转十进制{int i,j;int temp;int arry[16][4];for(i=0;i<n/4;i++){for(j=0;j<4;j++){arry[i][j]=a[4*i+j];}}for (i=0;i<n/4;i++){temp=arry[i][0]*8+arry[i][1]*4+arry[i][2]*2+arry[i][3]*1;/*for(j=3;j>=0;j--){if(arry[i][j]==1){t=1;for(k=0;k<3-j;k++){t=t*2;}}}*/b[i]=temp;}}void To102(int a[], int b[],int n)//二进制转十进制{int i,j;int temp;int arry[8][8];int t=1,k;for(i=0;i<n/8;i++){for(j=0;j<8;j++){arry[i][j]=a[8*i+j];}}for (i=0;i<n/8;i++){temp=0;for(j=7;j>=0;j--){if(arry[i][j]==1){t=1;for(k=0;k<7-j;k++){t=t*2;}temp+=t;}}b[i]=temp;}}void F_Function(int a[32],int b[32],int n) //F函数{int i;int tmp[48];int tep[32];Replacement(a,E_Table,tmp,48); //扩展变换E /*printf("\n第%d轮E盒扩展结果:",n);for(i=0;i<48;i++){if(i%8==0)printf(" ");printf("%d",tmp[i]);}*/for(i=0;i<48;i++) //与子密钥异或{tmp[i] ^= K[n][i];}/*printf("\n进入S盒的48比特:");for(i=0;i<48;i++){if(i%6==0){printf(" ");}printf("%d",tmp[i]);}*/S_compress(tmp,tep); //压缩变换SReplacement(tep,P_Table,b,32); //置换运算P/*printf("\n第%d次P置盒输出:",l++);for(i=0;i<32;i++){if(i%8==0)printf(" ");printf("%d",b[i]);}*//*printf("\nf[%d]的输出结果:",n);for(i=0;i<32;i++){if(i%8==0){printf(" ");}printf("%d",b[i]);}*/}void Encryption(int m0[64],int c1[64]){int i,k;int arry[32];int c0[64],m1[64];Replacement(m0,IP_Table,m1,64); //初始置换IP/*printf("\n初始置换:");for(i=0;i<64;i++){if(i%8==0)printf(" ");printf("%d",m1[i]);}*/for(i=0;i<32;i++){L[0][i]=m1[i];R[0][i]=m1[i+32];}k=1;while(k<17){F_Function(R[k-1],arry,k-1);for(i=0;i<32;i++){L[k][i]=R[k-1][i];R[k][i]=L[k-1][i]^arry[i];}k++;}for(i=0;i<32;i++){c0[i]=R[16][i];c0[i+32]=L[16][i];}Replacement(c0,IP_1_Table,c1,64); //逆初始置换}void changeKey(int a[16][48]){int i,j;int tmp[16][48];for(i=0;i<16;i++)for(j=0;j<48;j++){tmp[i][j]=a[i][j];}}for(i=0;i<16;i++){for(j=0;j<48;j++){K[i][j]=tmp[15-i][j];}}}void Decryption(int c1[],int m[]){int c0[64],t[64];int i,k;int arry[32];changeKey(K);/*printf("\n交换后的密钥:\n");for(i=0;i<16;i++){printf("\n");for(j=0;j<48;j++){if(j%8==0){printf(" ");}printf("%d",K[i][j]);}}*/Replacement(c1,IP_Table,c0,64); //初始IP for(i=0;i<32;i++){L[0][i]=c0[i];R[0][i]=c0[i+32];}k=1;while(k<17)F_Function(R[k-1],arry,k-1);for(i=0;i<32;i++){L[k][i]=R[k-1][i];R[k][i]=L[k-1][i]^arry[i];}k++;}for(i=0;i<32;i++){t[i]=R[16][i];t[i+32]=L[16][i];}Replacement(t,IP_1_Table,m,64); //逆初始置换}void print() //输出函数{int i;int a[12],b[12],d[3][16];int p[64],q[64];for(i=0;i<32;i++){p[i]=L[15][i];p[32+i]=R[15][i];q[i]=R[16][i];q[i+32]=L[16][i];}To10(K[14],a,48);To10(K[15],b,48);To10(c,d[0],64);To10(p,d[1],64);To10(q,d[2],64);printf("\n\t\t15轮密钥:");for(i=0;i<12;i++){printf("%x",a[i]);}printf("\t15轮结果:");for(i=0;i<16;i++){printf("%X",d[1][i]);printf("\n\t\t16轮密钥:");for(i=0;i<12;i++){printf("%X",b[i]);}printf("\t16轮结果:");for(i=0;i<16;i++){printf("%X",d[2][i]);}printf("\n\t\t最后结果:");for(i=0;i<16;i++){printf("%X",d[0][i]);}/*printf("\n最后结果二进制:");for(i=0;i<64;i++){printf("%d",c[i]);}*/}int main(){int num,i,t;char s1[8],s2[8];int m[64]; //m存放二进制明文/密文int d[64]; //存放二进制密钥int s[8];show1();printf("\t\tinput you choice:");while(1){scanf("%d",&num);switch(num){case 1:system("cls"); //调用清屏函数show2();{scanf("%d",&num);if(num==1){while(strlen(s1)!=8){printf("\t\t请输入明文(8):");scanf("%s",s1);}To2Bin(s1,m); //将明文转换成二进制流while(strlen(s2)!=8){printf("\t\t请输入密钥(8):");scanf("%s",s2);}To2Bin(s2,d); //将密钥转换成二进制/*printf("\n初始二进制明文:");for(i=0;i<64;i++){printf("%d",m[i]);}*//*printf("\n初始二进制密钥:");for(i=0;i<64;i++){printf("%d",d[i]);}*/SubKey(d);/*printf("\n16轮子密钥如下:");for(i=0;i<16;i++){printf("\nK[%d]:",i+1);for(j=0;j<48;j++){if(j%8==0)printf(" ");printf("%d",K[i][j]);}}*/Encryption(m,c);/*printf("\n16次迭代左结果:");for(i=0;i<17;i++){printf("\nL[%d]:",i);for(j=0;j<32;j++){if(j%8==0){printf(" ");}printf("%d",L[i][j]);}}printf("\n16次迭代右结果:");for(i=0;i<17;i++){printf("\nR[%d]:",i);for(j=0;j<32;j++){if(j%8==0){printf(" ");}printf("%d",R[i][j]);}}*/print();/*printf("\n二进制密文:");for(i=0;i<64;i++){printf("%d",c[i]);}*/printf("\n\t\t按0将此密文解密,1返回上一层,2返回主界面,其他键退出.....");scanf("%d",&t);if(t==0){int s[8];int a[64];Decryption(c,a);/*printf("\n解密后的二进制:");for(i=0;i<64;i++){printf("%d",a[i]);}*/To102(a,s,64);printf("\n\t\t解密结果:");for(i=0;i<8;i++){printf("%c",s[i]);}printf("\n\t\t按1加密,2解密,3退出");}else if(t==1){system("cls");show2();}else if(t==2){system("cls");show1();}else{exit(0);}}else if(num==2){char str1[20],str2[20];printf("\t\t请输入明文文件名:");scanf("%s",str1);reader(str1,s1);To2Bin(s1,m);printf("\t\t请输入密钥文件名:");scanf("%s",str2);reader(str2,s2);To2Bin(s2,d);SubKey(d);Encryption(m,c);print();printf("\n\t\t按0将此密文解密,1将密文存入文件,2返回主界面,其他键退出.....");scanf("%d",&t);if(t==0){int a[64];Decryption(c,a);/*printf("\n解密后的二进制:");for(i=0;i<64;i++){printf("%d",a[i]);}*/To102(a,s,64);printf("\n\t\t解密结果:");for(i=0;i<8;i++){printf("%c",s[i]);}printf("\n\t\t按1加密,2解密,3退出");}else if(t==1){int a[16];char str[30];FILE *fw;printf("\n\t\t请输入文件名:");scanf("%s",str);fw=fopen(str,"w");if(fw==NULL){printf("\n\t\t文件打开失败!\n");}else{To10(c,a,64);for(i=0;i<16;i++){fprintf(fw,"%X",a[i]);}}fclose(fw);printf("\n\t\t密文保存成功!按1加密,2解密,3退出");}else if(t==2){system("cls");show1();}else{exit(0);}}else if(num==3){system("cls");exit(0);}else{printf("\n\t\t输入不正确,请重新输入:");}}break;case 2:{system("cls");printf("\n\n\t\t------------------DES解密----------------");while(strlen(s1)!=8){printf("\n\n\n\t\t请输入密文(8):");scanf("%s",s1);}To2Bin(s1,m);while(strlen(s2)!=8){printf("\t\t请输入密钥(8):");scanf("%s",s2);}To2Bin(s2,d);SubKey(d);Decryption(m,c);print();printf("\n\t\t按1返回上一层,2返回主界面,其他键退出.....");scanf("%d",&t);if(t==1){system("cls");printf("\n\n\t\t---------------DES解密-------------");while(strlen(s1)!=8){printf("\n\n\t\t请输入密文(8):");scanf("%s",s1);}To2Bin(s1,m);while(strlen(s2)!=8){printf("\t\t请输入密钥(8):");scanf("%s",s);}To2Bin(s2,d);SubKey(d);Decryption(m,c);print();}else if(t==2){system("cls");show1();}else{exit(0);}}break;case 3:system("cls");exit(0);default:printf("输入不正确,请重新输入:");}}return 0;}说明:程序中有大部分的注释代码,去掉注释可查看各部分中间结果,如:十六轮子密钥,十六轮结果等程序运行主界面:加密界面:运行结果一:运行结果二:。
加密算法 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语⾔实现利⽤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算法由于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算法实验报告
【精品】DES算法实验报告一、理论部分DES算法是一种对称加密算法,也是目前广泛应用的加密算法之一。
DES算法使用的是分组加密的思想,将明文数据分成一定长度的数据块,按照一定的算法进行加密,得到密文数据。
DES算法中的关键是密钥,只有持有正确密钥的人才能解密。
DES算法的密钥长度为64位,但由于存在弱密钥的问题,使用时需要特别注意。
DES算法的加密过程包括以下几个步骤:1、密钥的生成和处理:DES算法的密钥长度为64位,但由于存在弱密钥的问题,使用时需要使用程序进行特殊处理,以确保生成的密钥不为弱密钥。
2、初始置换(IP):将明文数据按照一定的规则进行置换,得到置换后的数据。
3、分组:将置换后的明文数据分成左半部分和右半部分。
4、轮函数(f函数):将右半部分进行扩展置换、异或运算、S盒代替、置换等操作,得到一个新的右半部分。
5、轮秘钥生成:生成本轮加密所需要的秘钥。
6、异或运算:将左半部分和右半部分进行异或运算,得到一个新的左半部分。
7、左右交换:将左右部分进行交换。
以上步骤循环执行16次,直到得到最终的密文数据。
二、实验部分本次实验使用C语言实现了DES算法的加密和解密过程。
具体实现过程包括以下几个部分:1、密钥的生成:使用DES算法生成64位密钥,其中包括了对弱密钥的处理。
2、置换:使用DES算法中的IP置换和IP逆置换进行数据置换。
3、轮函数:使用DES算法中的f函数进行一轮加密操作。
5、加密:循环执行16轮加密操作,得到密文数据。
以上实现过程全部基于DES算法的规范。
三、结果分析1、速度慢:由于DES算法采用的是分组加密的思想,需要执行多次操作才能得到最终结果。
因此本次实验的加密和解密速度相对较慢。
2、代码简单:本次实验的代码相对简单,只需要用到一些基本数据结构和算法即可实现DES算法的加密和解密过程。
但需要注意的是,由于DES算法本身的复杂性,代码实现中需要注意细节和边界问题。
四、总结本次实验使用C语言实现了DES算法的加密和解密过程,通过实验得到了一些结果。
C语言的DES和3DES算法能真正运行
Linux下c语言实现DES和3DES算法(2010-12-09 20:56:21)转载分类:IT技术标签:linuxcdes3des加解密对称算法it一、DES算法理论DES算法属于对称加密算法,在一些对安全性要求较高的交易中运用广泛,如支付行业等。
关于DES算法的理论,网上有很多文章都有详细的讲解,写得很好,我这里不再赘述,这里给出链接:,请朋友们自己去学习,我的代码也是依据这里的理论写的。
二、实现环境及文件a、环境:Redhat Linux + cb、实现文件:des.hdes.cmakefile三、代码1、des.h文件//功能:实现DES及3DES加解密的算法//作者:XXX//日期:2008-9-23#ifndef DES_H#define DES_Hstatic int pc_1_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};static int pc_2_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};static int ls_num_table[16]={1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1};static int ip_table[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};static int ip_1_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};static 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};static int 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};static int s_box_table[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, 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 Do_DES(char* strSrc, char* strKey, char* strDest, char flag); #endif2、des.c文件//功能:实现DES及3DES加解密的算法//作者:XXX//日期:2008-9-23#include <stdio.h>#include <stdlib.h>#include <string.h>#include "des.h"//函数声明int Do_DES(char* strSrc, char* strKey, char* strDest, char flag);int Do_3DES(char* strSrc, char* strKey, char* strDest, char flag);//主函数int main(int argc, char** argv){char src16[16+1],key16[16+1],key48[48+1],dest16[16+1];if(argc != 3){fprintf(stderr,"Usage: [%s -e|-d s|3]\n",argv[0]);exit(1);}if(strcmp(argv[2],"-s") == 0){if(strcmp(argv[1],"-e") == 0){fprintf(stderr,"Please input the string that you want to encrypt(16 hex number):\n");memset(src16,0,sizeof(src16));scanf("%s",src16);fprintf(stderr,"Please input the Key string(16 hex number):\n");memset(key16,0,sizeof(key16));scanf("%s",key16);memset(dest16,0,sizeof(dest16));Do_DES(src16,key16,dest16,'e');fprintf(stderr,"Result: [%s]\n",dest16);}else if(strcmp(argv[1],"-d") == 0){fprintf(stderr,"Please input the string that you want to decrypt(16 hex number):\n");memset(src16,0,sizeof(src16));scanf("%s",src16);fprintf(stderr,"Please input the Key string(16 hex number):\n");memset(key16,0,sizeof(key16));scanf("%s",key16);memset(dest16,0,sizeof(dest16));Do_DES(src16,key16,dest16,'d');fprintf(stderr,"Result: [%s]\n",dest16);}elsereturn -1;}else if(strcmp(argv[2],"-3") == 0){if(strcmp(argv[1],"-e") == 0){fprintf(stderr,"Please input the string that you want to encrypt(16 hex number):\n");memset(src16,0,sizeof(src16));scanf("%s",src16);fprintf(stderr,"Please input the Key string(16 hex number):\n");memset(key48,0,sizeof(key48));scanf("%s",key48);memset(dest16,0,sizeof(dest16));Do_3DES(src16,key48,dest16,'e');fprintf(stderr,"Result: [%s]\n",dest16);}else if(strcmp(argv[1],"-d") == 0){fprintf(stderr,"Please input the string that you want to decrypt(16 hex number):\n");memset(src16,0,sizeof(src16));scanf("%s",src16);fprintf(stderr,"Please input the Key string(16 hex number):\n");memset(key48,0,sizeof(key48));scanf("%s",key48);memset(dest16,0,sizeof(dest16));Do_3DES(src16,key48,dest16,'d');fprintf(stderr,"Result: [%s]\n",dest16);}elsereturn -1;}elsereturn -1;return 0;}//做DES加密或解密运算int Do_DES(char* strSrc, char* strKey, char* strDest, char flag){int i,j;unsigned char subKey[16][48+1],byte8[8+1],bits[64+1],strTmp[64+1]; unsigned char L0[32+1],R0[32+1],Lx[32+1],Rx[32+1];if(!( flag == 'e' || flag == 'E' || flag == 'd' || flag == 'D'))return -1;if(strSrc == NULL || strKey == NULL)return -2;if(flag == 'e' || flag == 'E'){memset(byte8,0,sizeof(byte8));BCDToByte(strKey, 16, byte8);memset(bits,0,sizeof(bits));ByteToBit(byte8, 8, bits);Des_GenSubKey(bits,subKey);BCDToByte(strSrc, 16, byte8);ByteToBit(byte8, 8, bits);Des_IP(bits, strTmp);memcpy(L0,strTmp,32);memcpy(R0,strTmp+32,32);for(i=0;i<16;i++){memcpy(Lx,R0,32);Des_F(R0,subKey[i],Rx);Do_XOR(L0,32,Rx);memcpy(L0,Lx,32);memcpy(R0,Rx,32);}memcpy(bits,R0,32);memcpy(bits+32,L0,32);Des_IP_1(bits,strTmp);BitToByte(strTmp,64,byte8);ByteToBCD(byte8,8,strDest);}else{memset(byte8,0,sizeof(byte8));BCDToByte(strKey, 16, byte8);memset(bits,0,sizeof(bits));ByteToBit(byte8, 8, bits);Des_GenSubKey(bits,subKey);BCDToByte(strSrc, 16, byte8);ByteToBit(byte8, 8, bits);Des_IP(bits, strTmp);memcpy(L0,strTmp,32);memcpy(R0,strTmp+32,32);for(i=0;i<16;i++){memcpy(Lx,R0,32);Des_F(R0,subKey[15-i],Rx);Do_XOR(L0,32,Rx);memcpy(L0,Lx,32);memcpy(R0,Rx,32);}memcpy(bits,R0,32);memcpy(bits+32,L0,32);Des_IP_1(bits,strTmp);BitToByte(strTmp,64,byte8);ByteToBCD(byte8,8,strDest);}return 0;}//做3DES加密或解密运算int Do_3DES(char* strSrc, char* strKey, char* strDest, char flag) {unsigned char strBCDKey[32+1],strByteKey[16+1]; unsigned char strMidDest1[16+1],strMidDest2[16+1]; unsigned char strLKey[16+1],strMKey[16+1],strRKey[16+1];if(!( flag == 'e' || flag == 'E' || flag == 'd' || flag == 'D'))return -1;if(strSrc == NULL || strKey == NULL)return -2;if(strlen(strKey) < 32)return -3;if(flag == 'e' || flag == 'E'){memset(strBCDKey,0,sizeof(strBCDKey));memcpy(strBCDKey,strKey,32);memset(strLKey,0,sizeof(strLKey));memcpy(strLKey,strBCDKey,16);memset(strRKey,0,sizeof(strRKey));memcpy(strRKey,strBCDKey+16,16);Do_DES(strSrc,strLKey,strMidDest1,'e');Do_DES(strMidDest1,strRKey,strMidDest2,'d');Do_DES(strMidDest2,strLKey,strMidDest1,'e');memcpy(strDest,strMidDest1,16);}else{memset(strBCDKey,0,sizeof(strBCDKey));memcpy(strBCDKey,strKey,32);memset(strLKey,0,sizeof(strLKey));memcpy(strLKey,strBCDKey,16);memset(strRKey,0,sizeof(strRKey));memcpy(strRKey,strBCDKey+16,16);Do_DES(strSrc,strLKey,strMidDest1,'d');Do_DES(strMidDest1,strRKey,strMidDest2,'e');Do_DES(strMidDest2,strLKey,strMidDest1,'d');memcpy(strDest,strMidDest1,16);}return 0;}//对输入的字节串作BCD编码扩展int ByteToBCD(unsigned char* bytes, int count,unsigned char* strBCD) {unsigned char cTmp;int i;for(i=0;i<count;i++){cTmp = (bytes[i] & 0xF0) >> 4;strBCD[i*2] = (cTmp > 9) ? cTmp - 10 + 'A' : cTmp + '0';cTmp = bytes[i] & 0x0F;strBCD[i*2+1] = (cTmp > 9) ? cTmp - 10 + 'A' : cTmp + '0';}return (count*2);}//把输入的BCD编码串还原成字节串int BCDToByte(unsigned char* strBCD, int count, unsigned char* bytes) {unsigned char cTmp;int i;for(i=0;i<count/2;i++){cTmp = strBCD[i*2];if(cTmp >= 'A' && cTmp <= 'F')cTmp = cTmp - 'A' + 10;else if(cTmp >= 'a' && cTmp <= 'f')cTmp = cTmp - 'a' + 10;elsecTmp &= 0x0F;bytes[i] = cTmp << 4;cTmp = strBCD[i*2+1];if(cTmp >= 'A' && cTmp <= 'F')cTmp = cTmp - 'A' + 10;else if(cTmp >= 'a' && cTmp <= 'f')cTmp = cTmp - 'a' + 10;elsecTmp &= 0x0F;bytes[i] += cTmp;}return (count/2);}//把字节串变成比特串int ByteToBit(unsigned char* bytes, int count, unsigned char* strBit) {unsigned char cTmp;int i,j;for(i=0;i<count;i++){cTmp = 0x80;for(j=0;j<8;j++){strBit[i*8+j] = (bytes[i] & cTmp) >> (7-j);cTmp = cTmp >> 1;}}return (count*8);}//把比特串变成字节串int BitToByte(unsigned char* strBit, int count, unsigned char* bytes) {unsigned char cTmp;int i,j;for(i=0;i<(count/8);i++){cTmp = 0x00;for(j=0;j<8;j++){cTmp += (strBit[i*8+j] << (7-j));}bytes[i] = cTmp;}return (count/8);}//做异或操作int Do_XOR(unsigned char* strSrc, int count, unsigned char* strDest) {int i;if(strSrc == NULL || strDest == NULL)return -1;for(i=0;i<count;i++)strDest[i] ^= strSrc[i];return 0;}//des算法PC-1变换,把64比特的密钥K变换成56比特int Des_PC_1(unsigned char* strIn, unsigned char* strOut){int i;for(i=0;i<56;i++)strOut[i] = strIn[pc_1_table[i]-1];return 56;}//des算法PC-2变换,把56比特变换成48比特int Des_PC_2(unsigned char* strIn, unsigned char* strOut){int i;for(i=0;i<48;i++)strOut[i] = strIn[pc_2_table[i]-1];return 48;}//des算法的循环左移位运算int Des_LS(unsigned char* strIn, int count, unsigned char* strOut){int i;for(i=0;i<28;i++)strOut[i] = strIn[(i+count)(];return 28;}//des算法中通过父密钥产生16个48比特位的子密钥int Des_GenSubKey(unsigned char* strKey, unsigned char strSubKey[16][48+1]) {unsigned char tmp[56+1],C0[28+1],D0[28+1],Cx[28+1],Dx[28+1];int i,j;memset(tmp,0,sizeof(tmp));memset(C0,0,sizeof(C0));memset(D0,0,sizeof(D0));memset(Cx,0,sizeof(Cx));memset(Dx,0,sizeof(Dx));Des_PC_1(strKey, tmp);memcpy(C0,tmp,28);memcpy(D0,tmp+28,28);for(i=0;i<16;i++){Des_LS(C0,ls_num_table[i],Cx);Des_LS(D0,ls_num_table[i],Dx);memcpy(tmp,Cx,28);memcpy(tmp+28,Dx,28);Des_PC_2(tmp,strSubKey[i]);memcpy(C0,Cx,28);memcpy(D0,Dx,28);}return 0;}//des算法IP置换int Des_IP(unsigned char* strIn, unsigned char* strOut) {int i;for(i=0;i<64;i++)strOut[i] = strIn[ip_table[i]-1];return 64;}//des算法IP-1置换int Des_IP_1(unsigned char* strIn, unsigned char* strOut) {int i;for(i=0;i<64;i++)strOut[i] = strIn[ip_1_table[i]-1];return 64;}//des算法e变换,将32比特变成48比特int Des_E(unsigned char* strIn, unsigned char* strOut) {int i;for(i=0;i<48;i++)strOut[i] = strIn[e_table[i]-1];return 48;}//des算法P变换int Des_P(unsigned char* strIn, unsigned char* strOut){int i;for(i=0;i<32;i++)strOut[i] = strIn[p_table[i]-1];return 32;}//des算法S盒变换int Des_S_Box(unsigned char* strIn, int nSBox, unsigned char* strOut) {int x,y,i,nValue;unsigned char c;if(nSBox < 1 || nSBox > 8)return -1;x = strIn[0] * 2 + strIn[5];y = strIn[1] * 8 + strIn[2] * 4 + strIn[3] * 2 + strIn[4];nValue = s_box_table[nSBox-1][x][y];c = 0x08;for(i=0;i<4;i++){strOut[i] = (nValue & c) >> (3 - i);c = c >> 1;}return 4;}//des算法F函数,对Ri-1和Ki进行运算int Des_F(unsigned char* strR, unsigned char* strK, unsigned char* strOut){int i,j,k;unsigned char strAftE[48],strPreP[32],sbIn[8][6],sbOut[8][4];for(i=0;i<48;i++)strAftE[i] = strR[e_table[i]-1];Do_XOR(strK, 48, strAftE);for(i=0;i<8;i++)for(j=0;j<6;j++)sbIn[i][j] = strAftE[i*6+j];for(i=0;i<8;i++)Des_S_Box(sbIn[i], i+1, sbOut[i]);for(i=0;i<32;i++)strPreP[i] = sbOut[i/4][i%4];Des_P(strPreP, strOut);return 32;}3、makefile文件all: des@echo 'Compile is OK'des: des.occ -o des des.o@rm des.odes.o: des.ccc -c des.c四、测试数据DES加密测试数据:src: 12345678(33738)key: 99999999(3939393939393939)ret: 3B2C7C7E6829AEDADES解密测试数据:src: 12345678(3B2C7C7E6829AEDA)key: 99999999(3939393939393939)ret: 337383DES加密测试数据:src: 12345678(33738)key: 9999999988888888(39393939393939393838383838383838) ret: 3B2C7C7E6829AEDA3DES解密测试数据:src: 3B2C7C7E6829AEDAkey: 9999999988888888(39393939393939393838383838383838) ret: 12345678(33738)。
DES实验报告
DES
[实验目的] C语言实现des加密解密
[实验原理]
1.DES的加密过程: 第一阶段:初始置换IP。在第一轮迭代之前,需要加密的64位明文首先通过初始置换IP 的作用,对输 入分组实施置换。最后,按照置换顺序,DES将64位的置换结果分为左右两部分,第1位到第32位记为 L0,第33位到第64位记为R0。 第二阶段:16次迭代变换。DES采用了典型的Feistel结构,是一个乘积结构的迭代密码算法。其算法的 核心是算法所规定的16次迭代变换。DES算法的16才迭代变换具有相同的结构,每一次迭代变换都以前 一次迭代变换的结果和用户密钥扩展得到的子密钥Ki作为输入;每一次迭代变换只变换了一半数据,它 们将输入数据的右半部分经过函数f后将其输出,与输入数据的左半部分进行异或运算,并将得到的结果 作为新的有半部分,原来的有半部分变成了新的左半部分。用下面的规则来表示这一过程(假设第i次迭 代所得到的结果为LiRi): Li = Ri-1; Ri = Li-1⊕ f(Ri-1,Ki);在最后一轮左与右半部分并未变换,而是直接 将R16 L16并在一起作为未置换的输入。 第三阶段:逆(初始)置换。 他是初始置换IP的逆置换,记为IP-1。在对16次迭代的结果(R16 L16) 再使用逆置换IP-1后,得到的结果即可作为DES加密的密文Y输出,即Y = IP-1 (R16 L16)。 2.DES解密过程: DES的解密算法与其加密算法使用的算法过程相同。两者的不同之处在于解密时子密钥Ki的使用顺序与 加密时相反,如果子密钥为K1K2… K16,那么解密时子密钥的使用顺序为K16K15… K1,即使用DES解密 算法进行解密时,将以64位密文作为输入,第1次迭代运算使用子密钥K16,第2次迭代运算使用子密钥 K15,… … ,第16 次迭代使用子密钥K1,其它的运算与加密算法相同。这样,最后输出的是64位明文。
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` 中使用。
C语言加密与解密算法
C语言加密与解密算法在计算机科学与信息安全领域,加密与解密算法起着至关重要的作用。
加密算法用于将原始数据转换为不可读的密文,而解密算法则用于将密文还原为可读的原始数据。
C语言是一种常用的编程语言,具备高效性和灵活性,适用于加密与解密算法的开发。
本文将介绍几种常用的C语言加密与解密算法。
一、凯撒密码算法凯撒密码算法是一种最简单的替换加密算法,通过将字母按照固定的偏移量进行替换来实现加密与解密。
以下是一个简单的C语言凯撒密码实现例子:```c#include <stdio.h>void caesarEncrypt(char* message, int key) {int i = 0;while (message[i] != '\0') {if (message[i] >= 'a' && message[i] <= 'z') {message[i] = (message[i] - 'a' + key) % 26 + 'a';} else if (message[i] >= 'A' && message[i] <= 'Z') {message[i] = (message[i] - 'A' + key) % 26 + 'A';}i++;}}void caesarDecrypt(char* message, int key) {int i = 0;while (message[i] != '\0') {if (message[i] >= 'a' && message[i] <= 'z') {message[i] = (message[i] - 'a' - key + 26) % 26 + 'a'; } else if (message[i] >= 'A' && message[i] <= 'Z') {message[i] = (message[i] - 'A' - key + 26) % 26 + 'A'; }i++;}}int main() {char message[] = "Hello, World!";int key = 3;printf("Original message: %s\n", message);caesarEncrypt(message, key);printf("Encrypted message: %s\n", message);caesarDecrypt(message, key);printf("Decrypted message: %s\n", message);return 0;}```以上程序演示了凯撒密码的加密与解密过程,通过指定偏移量实现对消息的加密与解密。
des密码算法实验c语言
des密码算法实验c语言以下是一个使用C语言实现DES密码算法的简单实验示例:```c#include <stdio.h>#include <stdlib.h>#include <string.h>#include <openssl/des.h>int main() {// 输入明文char plaintext[8] = "12345678";// 初始化DES密钥DES_cblock key = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF};DES_key_schedule keysched;DES_set_key_unchecked(&key, &keysched);// 加密unsigned char ciphertext[8];DES_cblock ivec = {0}; // 初始化向量DES_ncbc_encrypt(plaintext, ciphertext, sizeof(plaintext),&keysched, &ivec, DES_ENCRYPT);// 输出密文printf("Ciphertext: ");for (int i = 0; i < sizeof(plaintext); i++) {printf("%02X", ciphertext[i]);}printf("\n");// 解密unsigned char decryptedtext[8];memset(ivec, 0, sizeof(ivec)); // 重置初始化向量DES_ncbc_encrypt(ciphertext, decryptedtext, sizeof(plaintext), &keysched, &ivec, DES_DECRYPT);// 输出明文printf("Plaintext: ");for (int i = 0; i < sizeof(plaintext); i++) {printf("%c", decryptedtext[i]);}printf("\n");return 0;}```在这个实验中,我们使用了OpenSSL库中的DES函数来实现DES 密码算法。
des加密算法c语言源代码
#include<iostream.h>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};int IP_1[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};int E[48] = {32,1, 2, 3, 4, 5,4, 5, 6, 7, 8, 9,8, 9, 10,11,12,13,12,13,14,15,16,17,16,17,18,19,20,21,20,21,22,23,24,25,24,25,26,27,28,29,28,29,30,31,32,1};int 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 };void Char_to_Int(unsigned char in[],int out[],int len){for(int i=0;i<len;i++)out[i]=int(in[i]);}void Int_to_Char(int in[],unsigned char out[],int len){for(int i=0;i<len;i++)out[i]=char(in[i]);}void B_to_H(int in[],unsigned char out[]){for(int i=0;i<16;i++){int temp=in[i*4]*8+in[i*4+1]*4+in[i*4+2]*2+in[i*4+3];switch(temp){case 10 :out[i]='A';break;case 11 :out[i]='B';break;case 12 :out[i]='C';break;case 13 :out[i]='D';break;case 14 :out[i]='E';break;case 15 :out[i]='F';break;default :out[i]=unsigned char(temp+48);break;}}}void H_to_B(unsigned char in[],int out[]){for(int i=0;i<16;i++)switch(in[i]){case 'A':out[i*4]=1;out[i*4+1]=0;out[i*4+2]=1;out[i*4+3]=0;break;case 'B':out[i*4]=1;out[i*4+1]=0;out[i*4+2]=1;out[i*4+3]=1;break;case 'C':out[i*4]=1;out[i*4+1]=1;out[i*4+2]=0;out[i*4+3]=0;break;case 'D':out[i*4]=1;out[i*4+1]=1;out[i*4+2]=0;out[i*4+3]=1;break;case 'E':out[i*4]=1;out[i*4+1]=1;out[i*4+2]=1;out[i*4+3]=0;break;case 'F':out[i*4]=1;out[i*4+1]=1;out[i*4+2]=1;out[i*4+3]=1;break;case '0':out[i*4]=0;out[i*4+1]=0;out[i*4+2]=0;out[i*4+3]=0;break;case '1':out[i*4]=0;out[i*4+1]=0;out[i*4+2]=0;out[i*4+3]=1;break;case '2':out[i*4]=0;out[i*4+1]=0;out[i*4+2]=1;out[i*4+3]=0;break;case '3':out[i*4]=0;out[i*4+1]=0;out[i*4+2]=1;out[i*4+3]=1;break;case '4':out[i*4]=0;out[i*4+1]=1;out[i*4+2]=0;out[i*4+3]=0;break;case '5':out[i*4]=0;out[i*4+1]=1;out[i*4+2]=0;out[i*4+3]=1;break;case '6':out[i*4]=0;out[i*4+1]=1;out[i*4+2]=1;out[i*4+3]=0;break;case '7':out[i*4]=0;out[i*4+1]=1;out[i*4+2]=1;out[i*4+3]=1;break;case '8':out[i*4]=1;out[i*4+1]=0;out[i*4+2]=0;out[i*4+3]=0;break;case '9':out[i*4]=1;out[i*4+1]=0;out[i*4+2]=0;out[i*4+3]=1;break;}}void O_to_B(int in[],int out[],int len){int i,j;for(i=0;i<len;i++)for(j=i*len+7;j>=i*len;j--){out[j]=in[i]%2; in[i]=in[i]/2;}}void B_to_O(int in[],int out[],int len){int j;for(int i=0;i<len;i++){j=8*i;out[i]=in[j]*128+in[j+1]*64+in[j+2]*32+in[j+3]*16+in[j+4]*8+in[j+5]*4+in[j+6]*2+in[j+7]*1;}}void Convert(int in[],int out[],int table[],int len){for(int i=0;i<len;i++)out[i]=in[table[i]-1];}void Divide(int in[],int out1[],int out2[],int len){for(int i=0;i<len;i++)if(i<len/2)out1[i]=in[i];elseout2[i-len/2]=in[i];}//正确void Combine(int in1[],int in2[],int out[],int len){for(int i=0;i<len;i++)if(i<len/2)out[i]=in1[i];elseout[i]=in2[i-len/2];}//正确void RLC1(int in[],int out[],int len){int temp=in[0];for(int i=0;i<len-1;i++)out[i]=in[i+1];out[len-1]=temp;}//正确void RLC2(int in[],int out[],int len){int temp1=in[0],temp2=in[1];for(int i=0;i<len-2;i++)out[i]=in[i+2];out[len-2]=temp1;out[len-1]=temp2;}//正确void COPY(int in[],int out[],int len){for(int i=0;i<len;i++)out[i]=in[i];}//ZHENGQUEvoid XOR(int in1[],int in2[],int out[],int len){for(int i=0;i<len;i++)out[i]=(in1[i]+in2[i])%2;}void GetKey(unsigned char in[],int out[16][48]){int i;int Msg_Int[8],Msg_Bin[64],Msg_Bin_PC1[56],Key_Bin[56],C[17][28],D[17][28];char Msg_H[16];int PC1[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},PC2[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};Char_to_Int(in,Msg_Int,8);//正确O_to_B(Msg_Int,Msg_Bin,8);//正确cout<<endl;Convert(Msg_Bin,Msg_Bin_PC1,PC1,56); Divide(Msg_Bin_PC1,C[0],D[0],56);for(i=0;i<16;i++){if(i==0){RLC1(C[i],C[i+1],28);RLC1(D[i],D[i+1],28);}else if(i==1){RLC1(C[i],C[i+1],28);RLC1(D[i],D[i+1],28);}else if(i==8){RLC1(C[i],C[i+1],28);RLC1(D[i],D[i+1],28);}else if(i==15){RLC1(C[i],C[i+1],28);RLC1(D[i],D[i+1],28);}else{RLC2(C[i],C[i+1],28);RLC2(D[i],D[i+1],28);}Combine(C[i+1],D[i+1],Key_Bin,56);Convert(Key_Bin,out[i],PC2,48);}} //生成子密钥正确void S_box(int in[],int out[]){int i;int SBox[8][64] ={{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,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 s1,s3,s2[8];for(i=0;i<8;i++){s1=in[i*6]*2+in[i*6+5]*1;s3=in[i*6+1]*8+in[i*6+2]*4+in[i*6+3]*2+in[i*6+4]*1;s2[i]=SBox[i][s1*16+s3];}int j;for(i=0;i<8;i++)for(j=i*4+3;j>=i*4;j--){out[j]=s2[i]%2; s2[i]=s2[i]/2;}}void Encode(unsigned char in[],unsigned char Final_H[],int K[16][48]){int i;intORINT[8],ORBYTE[64],FinalBYTE[64],LR[64],R48[48],S_in[48],S_out[32],F_RL[32],FinalINT[8],L[17] [32],R[17][32];char ORH[16];Char_to_Int(in,ORINT,8);cout<<""<<endl;O_to_B(ORINT,ORBYTE,8);Convert(ORBYTE,LR,IP,64);Divide(LR,L[0],R[0],64);for(i=1;i<17;i++){Convert(R[i-1],R48,E,48);XOR(R48,K[i-1],S_in,48);S_box(S_in,S_out);Convert(S_out,F_RL,P,32);XOR(F_RL,L[i-1],R[i],32);COPY(R[i-1],L[i],32);}Combine(R[16],L[16],LR,64);Convert(LR,FinalBYTE,IP_1,64);cout<<"二进制的密文:"<<endl;for(i=0;i<64;i++){cout<<FinalBYTE[i];}cout<<endl<<endl;B_to_H(FinalBYTE,Final_H);}void DeCode(unsigned char in[],unsigned char Final_H[],int K[16][48]){int i;intORINT[8],ORBYTE[64],LR[64],R48[48],S_in[48],S_out[32],F_RL[32],FinalBYTE[64],FinalINT[8],L[17] [32],R[17][32];char ORH[16];Char_to_Int(in,ORINT,8);cout<<""<<endl;O_to_B(ORINT,ORBYTE,8);Convert(ORBYTE,LR,IP,64);Divide(LR,L[0],R[0],64);for(i=1;i<17;i++){COPY(R[i-1],L[i],32);Convert(R[i-1],R48,E,48);XOR(R48,K[16-i],S_in,48);S_box(S_in,S_out);Convert(S_out,F_RL,P,32);XOR(L[i-1],F_RL,R[i],32);}Combine(R[16],L[16],LR,64);Convert(LR,FinalBYTE,IP_1,64);B_to_H(FinalBYTE,Final_H);}void main(){int i;unsigned char Msg[8],UnCodeMsg[16],CodeMsg[16],Key[8],Msg_H[16],CodeChar[8];int SKey[16][48];int OrByte[64],OrInt[8],FinalByte[64],FinalInt[8];cout<<"请输入明文:"<<endl;for(i=0;i<8;i++)cin>>Msg[i];cout<<"请输入初始密钥:"<<endl;for(i=0;i<8;i++)cin>>Key[i];GetKey(Key,SKey);Encode(Msg,CodeMsg,SKey);cout<<"十六进制的密文:"<<endl;for(i=0;i<16;i++)cout<<CodeMsg[i];cout<<endl;cout<<"字符型密文:"<<endl;H_to_B(CodeMsg,FinalByte);B_to_O(FinalByte,FinalInt,8);Int_to_Char(FinalInt,CodeChar,8);for(i=0;i<8;i++)cout<<CodeChar[i];cout<<endl;cout<<"请输入十六进制的密文:"<<endl;for(i=0;i<16;i++)cin>>CodeMsg[i];B_to_O(FinalByte,FinalInt,8);Int_to_Char(FinalInt,CodeChar,8);cout<<"请输入解密密钥:"<<endl;for(i=0;i<8;i++)cin>>Key[i];GetKey(Key,SKey);DeCode(CodeChar,Msg_H,SKey);//for(i=0;i<16;i++)// cout<<Msg_H[i];cout<<endl;H_to_B(Msg_H,OrByte);B_to_O(OrByte,OrInt,8);Int_to_Char(OrInt,Msg,8);cout<<"明文是:"<<endl;for(i=0;i<8;i++)cout<<Msg[i];cout<<endl;}。
DES加密的算法
信息安全概论·课程设计DES加密的C语言实现目录摘要....................................................... 错误!未定义书签。
Abstract ................................................... 错误!未定义书签。
关键词..................................................... 错误!未定义书签。
1.算法描述................................................ 错误!未定义书签。
1.1加/解密算法的一般原理............................... 错误!未定义书签。
1.2加/解密机制的应用................................... 错误!未定义书签。
2.S盒设计................................................ 错误!未定义书签。
3.DES程序实例与分析...................................... 错误!未定义书签。
4.DES实例运行结果........................................ 错误!未定义书签。
5.结语.................................................... 错误!未定义书签。
6.参考文献................................................. 错误!未定义书签。
信息安全概论·课程设计DES加密的C语言实现C language achieve DES algorithm摘要DES算法是一种数据加密算法,自从1977年公布以来,一直是国际上的商用保密通信和计算机通信的最常用的加密标准。
DES加密C语言实现源代码
void *memcpy( void *dest, const void *src, unsigned char count ){// ASSERT((dest != NULL)&&(src != NULL));unsigned char *temp_dest = (unsigned char *)dest;unsigned char *temp_src = (unsigned char *)src;while(count--) // 不对是否存在重叠区域进行判断{*temp_dest++ = *temp_src++;}return dest;}unsigned char *memset(unsigned char *dst,unsigned char value,unsigned char count) {unsigned char *start = dst;while (count--)*dst++ = value;return(start);}// 初始置换表IPunsigned char IP_Table[64] = { 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,56,48,40,32,24,16,8,0,58,50,42,34,26,18,10,2,60,52,44,36,28,20,12,4,62,54,46,38,30,22,14,6};//逆初始置换表IP^-1unsigned char IP_1_Table[64] = {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,32,0,40,8,48,16,56,24};//扩充置换表Eunsigned char E_Table[48] = {31, 0, 1, 2, 3, 4,3, 4, 5, 6, 7, 8,7, 8,9,10,11,12,11,12,13,14,15,16,15,16,17,18,19,20,19,20,21,22,23,24,23,24,25,26,27,28,27,28,29,30,31, 0};//置换函数Punsigned char P_Table[32] = {15,6,19,20,28,11,27,16, 0,14,22,25,4,17,30,9,1,7,23,13,31,26,2,8,18,12,29,5,21,10,3,24};//S盒unsigned char 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}}};//置换选择1unsigned char PC_1[56] = {56,48,40,32,24,16,8, 0,57,49,41,33,25,17,9,1,58,50,42,34,26,18,10,2,59,51,43,35,62,54,46,38,30,22,14,6,61,53,45,37,29,21,13,5,60,52,44,36,28,20,12,4,27,19,11,3};//置换选择2unsigned char PC_2[48] = {13,16,10,23,0,4,2,27,14,5,20,9,22,18,11,3,25,7,15,6,26,19,12,1,40,51,30,36,46,54,29,39,50,44,32,46,43,48,38,55,33,52,45,41,49,35,28,31};// 对左移次数的规定unsigned char MOVE_TIMES[16] = {1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1}; //字节转换成二进制unsigned char ByteToBit(unsigned char ch, unsigned char bit[8]) {unsigned char cnt;for(cnt = 0;cnt < 8; cnt++){*(bit+cnt) = (ch>>cnt)&1;}return 0;}// 二进制转换成字节unsigned char BitToByte(unsigned char bit[8],unsigned char *ch){unsigned char cnt;for(cnt = 0;cnt < 8; cnt++){*ch |= *(bit + cnt)<<cnt;}return 0;}// 将长度为8的字符串转为二进制位串unsigned char Char8ToBit64(unsigned char ch[8],unsigned char bit[64]){unsigned char cnt;for(cnt = 0; cnt < 8; cnt++){ByteToBit(*(ch+cnt),bit+(cnt<<3));}return 0;}// 将二进制位串转为长度为8的字符串unsigned char Bit64ToChar8(unsigned char bit[64],unsigned char ch[8]){unsigned char cnt;memset(ch,0,8);for(cnt = 0; cnt < 8; cnt++){BitToByte(bit+(cnt<<3),ch+cnt);}return 0;}// 密钥置换1unsigned char DES_PC1_Transform(unsigned char key[64], unsigned char tempbts[56]) {unsigned char cnt;for(cnt = 0; cnt < 56; cnt++){tempbts[cnt] = key[PC_1[cnt]];}return 0;}//密钥置换2unsigned char DES_PC2_Transform(unsigned char key[56], unsigned char tempbts[48]) {unsigned char cnt;for(cnt = 0; cnt < 48; cnt++){tempbts[cnt] = key[PC_2[cnt]];}return 0;}//循环左移unsigned char DES_ROL(unsigned char data[56], unsigned char time){unsigned char temp[56];//保存将要循环移动到右边的位memcpy(temp,data,time);memcpy(temp+time,data+28,time);//前28位移动memcpy(data,data+time,28-time);memcpy(data+28-time,temp,time);//后28位移动memcpy(data+28,data+28+time,28-time);memcpy(data+56-time,temp+time,time);return 0;}//IP置换unsigned char DES_IP_Transform(unsigned char data[64]){unsigned char cnt;unsigned char temp[64];for(cnt = 0; cnt < 64; cnt++){temp[cnt] = data[IP_Table[cnt]];}memcpy(data,temp,64);return 0;}// IP逆置换unsigned char DES_IP_1_Transform(unsigned char data[64]) {unsigned char cnt;unsigned char temp[64];for(cnt = 0; cnt < 64; cnt++){temp[cnt] = data[IP_1_Table[cnt]];}memcpy(data,temp,64);return 0;}//扩展置换unsigned char DES_E_Transform(unsigned char data[48]) {unsigned char cnt;unsigned char temp[48];for(cnt = 0; cnt < 48; cnt++){temp[cnt] = data[E_Table[cnt]];}memcpy(data,temp,48);return 0;}//P置换unsigned char DES_P_Transform(unsigned char data[32]) {unsigned char cnt;unsigned char temp[32];for(cnt = 0; cnt < 32; cnt++){temp[cnt] = data[P_Table[cnt]];}memcpy(data,temp,32);return 0;}// 异或unsigned char DES_XOR(unsigned char R[48], unsigned char L[48] ,unsigned char count) {unsigned char cnt;for(cnt = 0; cnt < count; cnt++){R[cnt] ^= L[cnt];}return 0;}// S盒置换unsigned char DES_SBOX(unsigned char data[48]){unsigned char cnt;unsigned char line,row,output;unsigned char cur1,cur2;for(cnt = 0; cnt < 8; cnt++){cur1 = cnt*6;cur2 = cnt<<2;// 计算在S盒中的行与列line = (data[cur1]<<1) + data[cur1+5];row = (data[cur1+1]<<3) + (data[cur1+2]<<2)+ (data[cur1+3]<<1) + data[cur1+4];output = S[cnt][line][row];// 化为2进制data[cur2] = (output&0X08)>>3;data[cur2+1] = (output&0X04)>>2;data[cur2+2] = (output&0X02)>>1;data[cur2+3] = output&0x01;}return 0;}//交换unsigned char DES_Swap(unsigned char left[32], unsigned char right[32]){unsigned char temp[32];memcpy(temp,left,32);memcpy(left,right,32);memcpy(right,temp,32);return 0;}//生成子密钥unsigned char DES_MakeSubKeys(unsigned char key[64],unsigned char subKeys[16][48]) {unsigned char temp[56];unsigned char cnt;DES_PC1_Transform(key,temp);// PC1置换for(cnt = 0; cnt < 16; cnt++) //16轮跌代,产生16个子密钥{DES_ROL(temp,MOVE_TIMES[cnt]);// 循环左移DES_PC2_Transform(temp,subKeys[cnt]);//PC2置换,产生子密钥}return 0;}//加密单个分组unsigned char DES_EncryptBlock(unsigned char plainBlock[8], unsigned char subKeys[16][48], unsigned char cipherBlock[8]){unsigned char plainBits[64];unsigned char copyRight[48];unsigned char cnt;Char8ToBit64(plainBlock,plainBits);//初始置换(IP置换)DES_IP_Transform(plainBits);// 16轮迭代for(cnt = 0; cnt < 16; cnt++){memcpy(copyRight,plainBits+32,32);DES_E_Transform(copyRight); // 将右半部分进行扩展置换,从32位扩展到48位DES_XOR(copyRight,subKeys[cnt],48); // 将右半部分与子密钥进行异或操作DES_SBOX(copyRight); // 异或结果进入S盒,输出32位结果 DES_P_Transform(copyRight); // P置换DES_XOR(plainBits,copyRight,32); //将明文左半部分与右半部分进行异或 if(cnt != 15){DES_Swap(plainBits,plainBits+32);//最终完成左右部的交换}}DES_IP_1_Transform(plainBits); //逆初始置换(IP^1置换)Bit64ToChar8(plainBits,cipherBlock);return 0;}// 解密单个分组unsigned char DES_DecryptBlock(unsigned char cipherBlock[8], unsigned char subKeys[16][48],unsigned char plainBlock[8]){unsigned char cipherBits[64];unsigned char copyRight[48];short cnt;Char8ToBit64(cipherBlock,cipherBits);//初始置换(IP置换)DES_IP_Transform(cipherBits);// 16轮迭代for(cnt = 15; cnt >= 0; cnt--){memcpy(copyRight,cipherBits+32,32);//将右半部分进行扩展置换,从32位扩展到48位DES_E_Transform(copyRight);// 将右半部分与子密钥进行异或操作DES_XOR(copyRight,subKeys[cnt],48);//异或结果进入S盒,输出32位结果DES_SBOX(copyRight);// P置换DES_P_Transform(copyRight);//将明文左半部分与右半部分进行异或DES_XOR(cipherBits,copyRight,32);if(cnt != 0){// 最终完成左右部的交换DES_Swap(cipherBits,cipherBits+32);}}// 逆初始置换(IP^1置换)DES_IP_1_Transform(cipherBits);Bit64ToChar8(cipherBits,plainBlock);return 0;}//加密文件unsigned char DES_Encrypt(unsigned char *keyStr,unsigned char *plainFile,unsigned char *cipherFile){unsigned char keyBlock[8],bKey[64],subKeys[16][48];memcpy(keyBlock,keyStr,8); //设置密钥Char8ToBit64(keyBlock,bKey); //将密钥转换为二进制流 DES_MakeSubKeys(bKey,subKeys); //生成子密钥DES_EncryptBlock(plainFile,subKeys,cipherFile);return 1;}//解密文件unsigned char DES_Decrypt(unsigned char *keyStr,unsigned char *cipherFile,unsigned char *plainFile){// unsigned char plainBlock[8],cipherBlock[8],unsigned char bKey[64],keyBlock[8],subKeys[16][48];memcpy(keyBlock,keyStr,8); //设置密钥Char8ToBit64(keyBlock,bKey); //将密钥转换为二进制流 DES_MakeSubKeys(bKey,subKeys); //生成子密钥DES_DecryptBlock(cipherFile,subKeys,plainFile);return 1;}/****************************************************************************** ****************** 作者:win2kddk* 说明:3重DES是使用16字节密钥将8字节明文数据块进行3次DES加密和解密。
DES算法实现(C++版)
DES算法实现(C++版)1 #include "memory.h"2 #include "stdio.h"3enum {encrypt,decrypt};//ENCRYPT:加密,DECRYPT:解密4void des_run(char out[8],char in[8],bool type=encrypt);5//设置密钥6void des_setkey(const char key[8]);7static void f_func(bool in[32],const bool ki[48]);//f函数8static void s_func(bool out[32],const bool in[48]);//s盒代替9//变换10static void transform(bool *out, bool *in, const char *table, int len);11static void xor(bool *ina, const bool *inb, int len);//异或12static void rotatel(bool *in, int len, int loop);//循环左移13//字节组转换成位组14static void bytetobit(bool *out,const char *in, int bits);15//位组转换成字节组16static void bittobyte(char *out, const bool *in, int bits);17//置换IP表18const static char ip_table[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 19//逆置换IP-1表20const static char 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 21//E 位选择表22static const char 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};23//P换位表24const 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};25//pc1选位表26const static char pc1_table[56]={2757,49,41,33,25,17,9,1,2858,50,42,34,26,18,10,2,2959,51,43,35,27,19,11,3,3060,52,44,36,63,55,47,39,3131,23,15,7,62,54,46,38,3230,22,14,6,61,53,45,37,3329,21,13,5,28,20,12,434 };35//pc2选位表36const static char pc2_table[48]={3714,17,11,24,1,5,3,28,3815,6,21,10,23,19,12,4,3926,8,16,7,27,20,13,2,4041,52,31,37,47,55,30,40,4151,45,33,48,44,49,39,56,4234,53,46,42,50,36,29,3243 };44//左移位数表45const static char loop_table[16]={1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1};46//S盒47const static char s_box[8][4][16]={48//s14914, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,500, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,514, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,5215, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13,53//s25415, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,553, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,560, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,5713, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9,58//s35910, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,6013, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,6113, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,621, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12,63//s4647, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,6513, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,6610, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,673, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14,68//s5692, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,7014, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,714, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,7211, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3,73//s67412, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,7510, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,769, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,774, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13,78//s7794, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,8013, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,811, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,826, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12,83//s88413, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,851, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,867, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,872, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 1188 };89static bool subkey[16][48];//16圈⼦密钥90void des_run(char out[8],char in[8], bool type)91 {92static bool m[64],tmp[32],*li=&m[0], *ri=&m[32];93 bytetobit(m,in,64);94 transform(m,m,ip_table,64);95if(type==encrypt){96for(int i=0;i<16;i++){97 memcpy(tmp,ri,32);98 f_func(ri,subkey[i]);99 xor(ri,li,32);100 memcpy(li,tmp,32);101 }102 }else{103for(int i=15;i>=0;i--){104 memcpy(tmp,li,32);105 f_func(li,subkey[i]);106 xor(li,ri,32);107 memcpy(ri,tmp,32);108 }109 }110 transform(m,m,ipr_table,64);111 bittobyte(out,m,64);112 }113void des_setkey(const char key[8])114 {115static bool k[64], *kl=&k[0], *kr=&k[28];116 bytetobit(k,key,64);117 transform(k,k,pc1_table,56);118for(int i=0;i<16;i++)119 {120 rotatel(kl,28,loop_table[i]);121 rotatel(kr,28,loop_table[i]);122 transform(subkey[i],k,pc2_table,48);123 }124 }125void f_func(bool in[32],const bool ki[48])126 {127static bool mr[48];128 transform(mr,in,e_table,48);129 xor(mr,ki,48);130 s_func(in,mr);131 transform(in,in,p_table,32);132 }133void s_func(bool out[32],const bool in[48])134 {135for(char i=0,j,k;i<8;i++,in+=6,out+=4)136 {137 j=(in[0]<<1)+in[5];138 k=(in[1]<<3)+(in[2]<<2)+(in[3]<<1)+in[4];139 bytetobit(out,&s_box[i][j][k],4);140 }141 }142void transform(bool *out,bool *in,const char *table,int len) 143 {144static bool tmp[256];145for(int i=0;i<len;i++)146 tmp[i]=in[table[i]-1];147 memcpy(out,tmp,len);148 }149void xor(bool *ina,const bool *inb,int len)150 {151for(int i=0;i<len;i++)152 ina[i]^=inb[i];153 }154void rotatel(bool *in,int len,int loop)155 {156static bool tmp[256];157 memcpy(tmp,in,loop);158 memcpy(in,in+loop,len-loop);159 memcpy(in+len-loop,tmp,loop);160 }161void bytetobit(bool *out,const char *in,int bits)162 {163for(int i=0;i<bits;i++)164out[i]=(in[i/8]>>(i%8)) &1;165 }166void bittobyte(char *out,const bool *in,int bits)167 {168 memset(out,0,(bits+7)/8);169for(int i=0;i<bits;i++)170out[i/8]|=in[i]<<(i%8);171 }172void main()173 {174char key[8]={'p','r','o','g','r','a','m'},str[8];175 puts("*****************DES***********************");176 printf("\n");177 printf("\n");178 puts("please input your words");179 gets(str);180 printf("\n");181 puts("****************************************");182 des_setkey(key);183 des_run(str,str,encrypt);184 puts("after encrypting:");185 puts(str);186 printf("\n");187 puts("****************************************");188 puts("after decrypting:");189 des_run(str,str,decrypt);190 puts(str);191 printf("\n");192 puts("****************************************");193 printf("\n");194 }。
C#加密解密(DES,AES,Base64,md5,SHA256,RSA,RC4)
C#加密解密(DES,AES,Base64,md5,SHA256,RSA,RC4)⼀:异或^简单加解密(数字类型)1:原理:异或⽤于⽐较两个⼆进制数的相应位,在执⾏按位"异或"运算时,如果两个⼆进制数的相应位都为1或者都为0,则返回0;如果两个⼆进制数的相应位其中⼀个为1另⼀个为0,则返回1.//对数字加密int P_int_Num, P_int_Key;//定义两个值类型变量string Encryptstr = (P_int_Num ^ P_int_Key).ToString();//加密数值//对数字解密int P_int_Key, P_int_Encrypt;//定义两个值类型变量string Encryptstr =(P_int_Encrypt ^ P_int_Key).ToString();//解密数值⼆:加密解密类public class JiaMiJieMi{#region DES对称加密解密///<summary>加密字符串///</summary>///<param name="strText">需被加密的字符串</param>///<param name="strEncrKey">密钥</param>///<returns></returns>public static string DesEncrypt(string strText, string strEncrKey){try{byte[] byKey = null;byte[] IV = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };byKey = Encoding.UTF8.GetBytes(strEncrKey.Substring(0, 8));DESCryptoServiceProvider des = new DESCryptoServiceProvider();byte[] inputByteArray = Encoding.UTF8.GetBytes(strText);MemoryStream ms = new MemoryStream();CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(byKey, IV), CryptoStreamMode.Write);cs.Write(inputByteArray, 0, inputByteArray.Length);cs.FlushFinalBlock();return Convert.ToBase64String(ms.ToArray());}catch{return"";}}///<summary>解密字符串///</summary>///<param name="strText">需被解密的字符串</param>///<param name="sDecrKey">密钥</param>///<returns></returns>public static string DesDecrypt(string strText, string sDecrKey){try{byte[] byKey = null;byte[] IV = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };byte[] inputByteArray = new Byte[strText.Length];byKey = Encoding.UTF8.GetBytes(sDecrKey.Substring(0, 8));DESCryptoServiceProvider des = new DESCryptoServiceProvider();inputByteArray = Convert.FromBase64String(strText);MemoryStream ms = new MemoryStream();CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(byKey, IV), CryptoStreamMode.Write);cs.Write(inputByteArray, 0, inputByteArray.Length);cs.FlushFinalBlock();Encoding encoding = new UTF8Encoding();return encoding.GetString(ms.ToArray());}catchreturn null;}}///<summary>加密⽂件//////</summary>///<param name="m_InFilePath">原路径</param>///<param name="m_OutFilePath">加密后的⽂件路径</param>///<param name="strEncrKey">密钥</param>public static void DesEncryptFile(string m_InFilePath, string m_OutFilePath, string strEncrKey){try{byte[] byKey = null;byte[] IV = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };byKey = Encoding.UTF8.GetBytes(strEncrKey.Substring(0, 8));FileStream fin = new FileStream(m_InFilePath, FileMode.Open, FileAccess.Read);FileStream fout = new FileStream(m_OutFilePath, FileMode.OpenOrCreate, FileAccess.Write);fout.SetLength(0);//Create variables to help with read and write.byte[] bin = new byte[100]; //This is intermediate storage for the encryption.long rdlen = 0; //This is the total number of bytes written.long totlen = fin.Length; //This is the total length of the input file.int len; //This is the number of bytes to be written at a time.DES des = new DESCryptoServiceProvider();CryptoStream encStream = new CryptoStream(fout, des.CreateEncryptor(byKey, IV), CryptoStreamMode.Write);//Read from the input file, then encrypt and write to the output file.while (rdlen < totlen){len = fin.Read(bin, 0, 100);encStream.Write(bin, 0, len);rdlen = rdlen + len;}encStream.Close();fout.Close();fin.Close();}catch{}}///<summary>解密⽂件//////</summary>///<param name="m_InFilePath">被解密路径</param>///<param name="m_OutFilePath">解密后的路径</param>///<param name="sDecrKey">密钥</param>public static void DesDecryptFile(string m_InFilePath, string m_OutFilePath, string sDecrKey){try{byte[] byKey = null;byte[] IV = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };byKey = Encoding.UTF8.GetBytes(sDecrKey.Substring(0, 8));FileStream fin = new FileStream(m_InFilePath, FileMode.Open, FileAccess.Read);FileStream fout = new FileStream(m_OutFilePath, FileMode.OpenOrCreate, FileAccess.Write);fout.SetLength(0);//Create variables to help with read and write.byte[] bin = new byte[100]; //This is intermediate storage for the encryption.long rdlen = 0; //This is the total number of bytes written.long totlen = fin.Length; //This is the total length of the input file.int len; //This is the number of bytes to be written at a time.DES des = new DESCryptoServiceProvider();CryptoStream encStream = new CryptoStream(fout, des.CreateDecryptor(byKey, IV), CryptoStreamMode.Write);//Read from the input file, then encrypt and write to the output file.while (rdlen < totlen){len = fin.Read(bin, 0, 100);encStream.Write(bin, 0, len);rdlen = rdlen + len;}encStream.Close();fout.Close();fin.Close();catch{}}#endregion#region对称加密算法AES RijndaelManaged加密解密private static readonly string Default_AES_Key = "@#kim123";private static byte[] Keys = { 0x41, 0x72, 0x65, 0x79, 0x6F, 0x75, 0x6D, 0x79,0x53,0x6E, 0x6F, 0x77, 0x6D, 0x61, 0x6E, 0x3F };public static string AES_Encrypt(string encryptString){return AES_Encrypt(encryptString, Default_AES_Key);}public static string AES_Decrypt(string decryptString){return AES_Decrypt(decryptString, Default_AES_Key);}///<summary>对称加密算法AES RijndaelManaged加密(RijndaelManaged(AES)算法是块式加密算法) //////</summary>///<param name="encryptString">待加密字符串</param>///<param name="encryptKey">加密密钥,须半⾓字符</param>///<returns>加密结果字符串</returns>public static string AES_Encrypt(string encryptString, string encryptKey){encryptKey = GetSubString(encryptKey, 32, "");encryptKey = encryptKey.PadRight(32, '');RijndaelManaged rijndaelProvider = new RijndaelManaged();rijndaelProvider.Key = Encoding.UTF8.GetBytes(encryptKey.Substring(0, 32));rijndaelProvider.IV = Keys;ICryptoTransform rijndaelEncrypt = rijndaelProvider.CreateEncryptor();byte[] inputData = Encoding.UTF8.GetBytes(encryptString);byte[] encryptedData = rijndaelEncrypt.TransformFinalBlock(inputData, 0, inputData.Length);return Convert.ToBase64String(encryptedData);}///<summary>对称加密算法AES RijndaelManaged解密字符串//////</summary>///<param name="decryptString">待解密的字符串</param>///<param name="decryptKey">解密密钥,和加密密钥相同</param>///<returns>解密成功返回解密后的字符串,失败返回空</returns>public static string AES_Decrypt(string decryptString, string decryptKey){try{decryptKey = GetSubString(decryptKey, 32, "");decryptKey = decryptKey.PadRight(32, '');RijndaelManaged rijndaelProvider = new RijndaelManaged();rijndaelProvider.Key = Encoding.UTF8.GetBytes(decryptKey);rijndaelProvider.IV = Keys;ICryptoTransform rijndaelDecrypt = rijndaelProvider.CreateDecryptor();byte[] inputData = Convert.FromBase64String(decryptString);byte[] decryptedData = rijndaelDecrypt.TransformFinalBlock(inputData, 0, inputData.Length);return Encoding.UTF8.GetString(decryptedData);}catch{return string.Empty;}}///<summary>///按字节长度(按字节,⼀个汉字为2个字节)取得某字符串的⼀部分///</summary>///<param name="sourceString">源字符串</param>///<param name="length">所取字符串字节长度</param>///<param name="tailString">附加字符串(当字符串不够长时,尾部所添加的字符串,⼀般为"...")</param> ///<returns>某字符串的⼀部分</returns>private static string GetSubString(string sourceString, int length, string tailString){return GetSubString(sourceString, 0, length, tailString);}///<summary>///按字节长度(按字节,⼀个汉字为2个字节)取得某字符串的⼀部分///</summary>///<param name="sourceString">源字符串</param>///<param name="startIndex">索引位置,以0开始</param>///<param name="length">所取字符串字节长度</param>///<param name="tailString">附加字符串(当字符串不够长时,尾部所添加的字符串,⼀般为"...")</param>///<returns>某字符串的⼀部分</returns>private static string GetSubString(string sourceString, int startIndex, int length, string tailString){string myResult = sourceString;//当是⽇⽂或韩⽂时(注:中⽂的范围:\u4e00 - \u9fa5, ⽇⽂在\u0800 - \u4e00, 韩⽂为\xAC00-\xD7A3)if (System.Text.RegularExpressions.Regex.IsMatch(sourceString, "[\u0800-\u4e00]+") ||System.Text.RegularExpressions.Regex.IsMatch(sourceString, "[\xAC00-\xD7A3]+")){//当截取的起始位置超出字段串长度时if (startIndex >= sourceString.Length){return string.Empty;}else{return sourceString.Substring(startIndex,((length + startIndex) > sourceString.Length) ? (sourceString.Length - startIndex) : length); }}//中⽂字符,如"中国⼈民abcd123"if (length <= 0){return string.Empty;}byte[] bytesSource = Encoding.Default.GetBytes(sourceString);//当字符串长度⼤于起始位置if (bytesSource.Length > startIndex){int endIndex = bytesSource.Length;//当要截取的长度在字符串的有效长度范围内if (bytesSource.Length > (startIndex + length)){endIndex = length + startIndex;}else{ //当不在有效范围内时,只取到字符串的结尾length = bytesSource.Length - startIndex;tailString = "";}int[] anResultFlag = new int[length];int nFlag = 0;//字节⼤于127为双字节字符for (int i = startIndex; i < endIndex; i++){if (bytesSource[i] > 127){nFlag++;if (nFlag == 3){nFlag = 1;}}else{nFlag = 0;}anResultFlag[i] = nFlag;}//最后⼀个字节为双字节字符的⼀半if ((bytesSource[endIndex - 1] > 127) && (anResultFlag[length - 1] == 1)){length = length + 1;}byte[] bsResult = new byte[length];Array.Copy(bytesSource, startIndex, bsResult, 0, length);myResult = Encoding.Default.GetString(bsResult);myResult = myResult + tailString;return myResult;}return string.Empty;}///<summary>///加密⽂件流///</summary>///<param name="fs"></param>///<returns></returns>public static CryptoStream AES_EncryptStrream(FileStream fs, string decryptKey){decryptKey = GetSubString(decryptKey, 32, "");decryptKey = decryptKey.PadRight(32, '');RijndaelManaged rijndaelProvider = new RijndaelManaged();rijndaelProvider.Key = Encoding.UTF8.GetBytes(decryptKey);rijndaelProvider.IV = Keys;ICryptoTransform encrypto = rijndaelProvider.CreateEncryptor();CryptoStream cytptostreamEncr = new CryptoStream(fs, encrypto, CryptoStreamMode.Write);return cytptostreamEncr;}///<summary>///解密⽂件流///</summary>///<param name="fs"></param>///<returns></returns>public static CryptoStream AES_DecryptStream(FileStream fs, string decryptKey){decryptKey = GetSubString(decryptKey, 32, "");decryptKey = decryptKey.PadRight(32, '');RijndaelManaged rijndaelProvider = new RijndaelManaged();rijndaelProvider.Key = Encoding.UTF8.GetBytes(decryptKey);rijndaelProvider.IV = Keys;ICryptoTransform Decrypto = rijndaelProvider.CreateDecryptor();CryptoStream cytptostreamDecr = new CryptoStream(fs, Decrypto, CryptoStreamMode.Read);return cytptostreamDecr;}///<summary>///对指定⽂件加密///</summary>///<param name="InputFile"></param>///<param name="OutputFile"></param>///<returns></returns>public static bool AES_EncryptFile(string InputFile, string OutputFile){try{string decryptKey = "";FileStream fr = new FileStream(InputFile, FileMode.Open);FileStream fren = new FileStream(OutputFile, FileMode.Create);CryptoStream Enfr = AES_EncryptStrream(fren, decryptKey);byte[] bytearrayinput = new byte[fr.Length];fr.Read(bytearrayinput, 0, bytearrayinput.Length);Enfr.Write(bytearrayinput, 0, bytearrayinput.Length);Enfr.Close();fr.Close();fren.Close();}catch{//⽂件异常return false;}return true;}///<summary>///对指定的⽂件解压缩///</summary>///<param name="InputFile"></param>///<param name="OutputFile"></param>///<returns></returns>public static bool AES_DecryptFile(string InputFile, string OutputFile){try{string decryptKey = "";FileStream fr = new FileStream(InputFile, FileMode.Open);FileStream frde = new FileStream(OutputFile, FileMode.Create);CryptoStream Defr = AES_DecryptStream(fr, decryptKey);byte[] bytearrayoutput = new byte[1024];int m_count = 0;do{m_count = Defr.Read(bytearrayoutput, 0, bytearrayoutput.Length);frde.Write(bytearrayoutput, 0, m_count);if (m_count < bytearrayoutput.Length)break;} while (true);Defr.Close();fr.Close();frde.Close();}catch{//⽂件异常return false;}return true;}#endregion#region Base64加密解密///<summary>/// Base64是⼀種使⽤64基的位置計數法。
C语言加密与解密算法详解
C语言加密与解密算法详解1. 引言在信息时代,数据的保密性至关重要。
加密与解密算法是一种重要的保护数据安全性的技术手段。
本文将详细介绍C语言中的加密与解密算法,包括常用的对称加密算法和非对称加密算法。
2. 对称加密算法2.1 Caesar密码Caesar密码是一种简单的替换密码算法,通过将每个字母向后移动固定的位数来加密消息。
解密操作是将每个字母向前移动相同的位数。
2.2 DES算法数据加密标准(DES)是一种对称加密算法,使用56位的密钥对64位的数据进行加密。
DES算法通过多轮迭代和复杂的置换与代换操作来实现高强度的加密。
3. 非对称加密算法3.1 RSA算法RSA算法是一种常用的非对称加密算法。
它通过使用两个密钥:一个公钥和一个私钥,来实现加密和解密操作。
发送方使用接收方的公钥进行加密,而接收方使用自己的私钥进行解密。
3.2 椭圆曲线加密算法椭圆曲线加密算法(ECC)是一种基于椭圆曲线数学原理的非对称加密算法。
它具有较小的密钥长度和高安全性的特点,适用于资源受限的设备。
4. 加密与解密实例4.1 使用Caesar密码加密与解密字符串下面是使用C语言实现Caesar密码算法的示例代码: ```// Caesar密码加密函数void caesarEncrypt(char* text, int key) {int i = 0;while (text[i] != '\0') {if (isalpha(text[i])) {if (islower(text[i])) {text[i] = (text[i] - 'a' + key) % 26 + 'a';} else {text[i] = (text[i] - 'A' + key) % 26 + 'A';}}i++;}}// Caesar密码解密函数void caesarDecrypt(char* text, int key) {caesarEncrypt(text, 26 - key);}```4.2 使用RSA算法加密与解密数据下面是使用C语言中的openssl库实现RSA算法的示例代码:```// RSA加密函数int rsaEncrypt(unsigned char* plainText, int plainTextLen, unsigned char* encryptedText) {// 使用公钥进行加密操作// ...}// RSA解密函数int rsaDecrypt(unsigned char* encryptedText, int encryptedTextLen, unsigned char* decryptedText) {// 使用私钥进行解密操作// ...}```5. 总结加密与解密算法在数据保密性方面发挥着重要的作用。
C#DES(cbc)加密解密(最简单的加密解密)
C#DES(cbc)加密解密(最简单的加密解密)微软官⽹的这个⽰例正的是该换了,⼀点⽤处没看出来/// <summary>/// DES CBC 加密/// </summary>/// <param name="encryStr"></param>/// <param name="key"></param>/// <param name="iv"></param>/// <returns></returns>public static string DesCBCEncryptor(string encryStr,string key,string iv){byte[] rgbKey = Encoding.UTF8.GetBytes(key);byte[] rgbIV = Encoding.UTF8.GetBytes(iv);byte[] inputByteArray = Encoding.UTF8.GetBytes(encryStr);DESCryptoServiceProvider dCSP = new DESCryptoServiceProvider();using (MemoryStream mStream = new MemoryStream()){using (CryptoStream cStream = new CryptoStream(mStream, dCSP.CreateEncryptor(rgbKey, rgbIV), CryptoStreamMode.Write)) {cStream.Write(inputByteArray, 0, inputByteArray.Length);cStream.FlushFinalBlock();byte[] srteamArray = mStream.ToArray();mStream.Close();mStream.Dispose();return Convert.ToBase64String(srteamArray);}}}/// <summary>/// DES CBC 解密/// </summary>/// <param name="decryStr"></param>/// <param name="key"></param>/// <param name="iv"></param>/// <returns></returns>public static string DesCBCDecryptor(string decryStr, string key, string iv){byte[] rgbKey = Encoding.UTF8.GetBytes(key);byte[] rgbIV = Encoding.UTF8.GetBytes(iv);byte[] inputByteArray = Convert.FromBase64String(decryStr);DESCryptoServiceProvider dCSP = new DESCryptoServiceProvider();using (MemoryStream mStream = new MemoryStream()){using (CryptoStream cStream = new CryptoStream(mStream, dCSP.CreateDecryptor(rgbKey, rgbIV), CryptoStreamMode.Write)) {cStream.Write(inputByteArray, 0, inputByteArray.Length);cStream.FlushFinalBlock();byte[] srteamArray = mStream.ToArray();mStream.Close();mStream.Dispose();return Encoding.UTF8.GetString(srteamArray);}}}。
C语言实现DES加密解密算法
C语言实现DES加密解密算法
最近几十年里,DES(Data Encryption Standard)算法的发展起到
了极其重要的作用。
Des算法是一种基于分组密码的算法。
算法将64位
的明文数据块按位分组成8个字节,每一组以8位为单位转换成一个64
位的密文数据块,采用16轮的分组加密,每次密码变化,保证加密强度。
本文详细介绍了DES算法的C语言实现,并分别介绍了加解密算法的实现
步骤以及DES加解密测试过程。
一、DES算法C语言实现
1.函数原型
DES算法的实现包括加密和解密函数,函数原型如下:
unsigned char* DesEncrypt(unsigned char *src, unsigned char
*key); // DES加密函数
unsigned char* DesDecrypt(unsigned char *src, unsigned char
*key); // DES解密函数
输入参数src是指明文源数据,key是加解密密钥,输出参数为一个
指向加解密结果的字符串指针。
2.加解密算法
(1)DES加密算法
DES加密算法步骤如下:
(i)初始置换:将64位明文块做一次IP置换得到L0R0。
(ii)迭代轮换:对L0R0经过16次迭代轮换后,最终结果为
L16R16
(iii)逆置换:L16R16进行逆置换得到64位密文。
(2)DES解密算法
DES解密算法步骤和DES加密算法步骤是一样的,只是将置换步骤改为逆置换,将轮换步骤改为逆轮换即可。
三、DES加解密测试
1.程序测试
在C语言编写完DES加解密算法之后。
C语言实现数据加密算法
C语言实现数据加密算法数据加密是对敏感信息进行转换的过程,以保护数据的机密性和完整性。
C语言提供了强大的工具和库来实现各种加密算法,包括对称加密和非对称加密等。
对称加密算法是一种使用相同密钥加密和解密数据的方法。
其中最常见的算法是DES(Data Encryption Standard)和AES(Advanced Encryption Standard)。
下面是一个实现AES算法的示例代码:```c#include <stdio.h>#include <stdlib.h>#include <string.h>#include <openssl/aes.h>void encrypt_data(const unsigned char *data, size_t len, const unsigned char *key, unsigned char *encrypted_data) AES_KEY aes_key;AES_set_encrypt_key(key, 128, &aes_key);AES_encrypt(data, encrypted_data, &aes_key);void decrypt_data(const unsigned char *encrypted_data,size_t len, const unsigned char *key, unsigned char *data) AES_KEY aes_key;AES_set_decrypt_key(key, 128, &aes_key);AES_decrypt(encrypted_data, data, &aes_key);int maiunsigned char data[AES_BLOCK_SIZE] = "hello world!";size_t len = sizeof(data);unsigned char encrypted_data[AES_BLOCK_SIZE];encrypt_data(data, len, key, encrypted_data);unsigned char decrypted_data[AES_BLOCK_SIZE];decrypt_data(encrypted_data, len, key, decrypted_data);printf("Original Data: %s\n", data);printf("Encrypted Data: ");for (int i = 0; i < len; i++)printf("%02x ", encrypted_data[i]);}printf("\nDecrypted Data: %s\n", decrypted_data);return 0;```以上代码使用了OpenSSL库中的AES加密算法。
DES加密算法的C语言实现
DES加密算法的C语言实现DES(Data Encryption Standard)是一种对称密钥加密算法,它的核心思想是将明文分成64位的数据块,并通过一系列的轮次操作对数据块进行加密,最终得到密文。
下面是一种用C语言实现DES加密算法的示例代码:```c#include <stdio.h>unsigned char initial_permutation(unsigned char block)unsigned char result = 0;result ,= (block & 0x80) >> 7;result ,= (block & 0x40) >> 5;result ,= (block & 0x20) >> 3;result ,= (block & 0x10) >> 1;result ,= (block & 0x08) << 1;result ,= (block & 0x04) << 3;result ,= (block & 0x02) << 5;result ,= (block & 0x01) << 7;return result;unsigned char final_permutation(unsigned char block)unsigned char result = 0;result ,= (block & 0x80) >> 7;result ,= (block & 0x40) >> 5;result ,= (block & 0x20) >> 3;result ,= (block & 0x10) >> 1;result ,= (block & 0x08) << 1;result ,= (block & 0x04) << 3;result ,= (block & 0x02) << 5;result ,= (block & 0x01) << 7;return result;void des_encrypt(unsigned char* plaintext, unsigned char* key, unsigned char* ciphertext)unsigned char block;unsigned char round_key;unsigned char i;// Initial Permutationblock = initial_permutation(*plaintext);// Round Permutationfor (i = 0; i < 16; i++)round_key = key[i];block ^= round_key;block = substitution(block);block = permutation(block);}// Final Permutation*ciphertext = final_permutation(block);int maiunsigned char plaintext = 0x55; // 明文unsigned char key[16] = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xEF, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}; // 密钥unsigned char ciphertext;des_encrypt(&plaintext, key, &ciphertext);printf("明文: 0x%02X\n", plaintext);printf("密钥: ");for (unsigned char i = 0; i < 16; i++)printf("%02X ", key[i]);}printf("\n");printf("密文: 0x%02X\n", ciphertext);return 0;```上述代码实现了DES算法的加密功能。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
}
for(i=0,j=0;i<8;i++,j=j+2)
{
jb[i]=ja[j]*16+ja[j+1];
}
ascii_to_erjinzhi(jb,jc);
//printf("\n二进制表示是:");
//print(jc,64,8);
return 1;
}
//printf("chenggong");
}
else
{
input_16(m_16,asciim,m);
}
return 1;
}
int miyaoinput()//密钥的输入
{
printf("\n请输入密钥:\n");
if(type==1)
{
int shuziinput(int *ja,int *jb)//以ascii码的数字的形式输入
{
int i;
for(i=0;i<8;i++)
{
scanf("%d",&ja[i]);
}
ascii_to_erjinzhi(ja,jb);
return 1;
}
int zifuinput(int *ja,int *jb)//以ascii码的字符形式输入
{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},
}
for(i=0;i<16;i++)
{
if(ja[i]<='9')
{
ja[i]=ja[i]-48;
}
else if(ja[i]>='A'&&ja[i]<='F')
{
ja[i]=ja[i]-55;
}
else
{
ja[i]=ja[i]-87;
getchar();
return 1;
}
int input(int signal)//输入明文或者密文函数
{
printf("请选择输入方式 (ASCII码字符形式输入1,ASCII码数字形式输入2,十六进制形式输入3)");
scanf("%d",&type);
if(signal==1)
{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},
33,1,41,9,49,17,57,25};
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,
}
switch(tempb)
{
ห้องสมุดไป่ตู้case 0:
jg[j]=0;
break;
case 1:
jg[j]=1;
break;
}
while(j%8!=0)
{
j--;
jg[j]=0;
}
j=(i+1)*8+7;
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,
{
printf("请输入明文:\n");
}
else if(signal==2)
{
printf("请输入密文:\n");
}
if(type==1)
{
zifuinput(asciim,m);
}
else if(type==2)
{
shuziinput(asciim,m);
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[32]={16,7,20,21,29,12,28,17,
int type;
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,
{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},
{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},
#include<stdio.h>
int asciim[8],m_16[16],m[64],asciik[8],k_16[16],k[64],m_ip[64],l[32],r[32],k_pc1[56],c[28],d[28],cd[56],k_pc2[48],re[48],sh[32],tempr[32],m0[64],m00[64],res[8];
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 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},
i--;
}
else
{
continue;
}
}
for(i=0;i<8;i++)
{
printf("%d ",ja[i]);
}
ascii_to_erjinzhi(ja,jb);
// printf("\n二进制表示是:");
// print(jb,64,8);
{
int i;
for(i=0;i<8;i++)
{
ja[i]=getchar();
if(ja[i]==' '||ja[i]=='\n')//如果没有换行符在密钥输入的时候密钥初始值就是10
{ //如果写的是换行时break是那么密钥不能输入,直接出结果。如果先调用密钥输入明文直接出结果
{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},
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 ip_1[64]={40,8,48,16,56,24,64,32,
39,7,47,15,55,23,63,31,
7,62,54,46,38,30,22,
14,6,61,53,45,37,29,
21,13,5,28,20,12,4};
int pc_2[48]={14,17,11,24,1,5,
3,28,15,6,21,10,
23,19,12,4,26,8,
{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},