DES加密算法

         DES 使用一个 56 位的密钥以及附加的 8 位奇偶校验位,产生最大 64 位的分组大小。这是一个迭代的分组密码,使用称为 Feistel 的技术,其中将加密的文本块分成两半。使用子密钥对其中一半应用循环功能,然后将输出与另一半进行“异或”运算;接着交换这两半,这一过程会继续下去,但最后一个循环不交换。DES 使用 16 个循环,使用异或,置换,代换,移位操作四种基本运算。
         自己写了一个DES加密算法,C语言版本,有很多不足,还望指正。
#include<stdio.h>

char painTest[1024]={0};							//明文数组
char ciphertext[1024]={0};							//密文数组
char password[8]={0};                                                           //密码数组
char painTestGroupBy64[128][8]={0};						//分组后的数组
char bitGrouping[64]={0};							//待处理的二进制数据(64位)
char passwordbit[64]={0};							//password密码二进制数据(64位)
char compressPassword[56]={0};							//压缩后的Password数组
char afterTeam[64]={0};							        //经过ip盒之后的二进制数据
int  groupNumber=0;								//分组数量
char C[17][28]={0};								//密码左部
char D[17][28]={0};							        //密码右部
char K[16][48]={0};                                                             //子密钥 
int  cNumber=0;
const int passwordCompressTable[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};

const int leftShiftTable[16]={                                                  //密钥左移参照表         
		1,  1,  2,  2,  2,  2,  2,  2,  
		1,  2,  2,  2,  2,  2,  2,  1};


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

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

const int dataExPermTable[48] = {						//32->扩散对照表
		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};

const int dataSBoxTable[8][4][16] = {					         //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},
		}
	};

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

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

char Base64[64]={
	'A','B','C','D','E','F','G','H',
		'I','J','K','L','M','N','O',
		'P','Q','R','S','T','U','V',
		'W','X','Y','Z','a','b','c',
		'd','e','f','g','h','i','j',
		'k','l','m','n','o','p','q',
		'r','s','t','u','v','w','x',
		'y','z','0','1','2','3','4',
		'5','6','7','8','9','+','/'};
/***********************************
*   函数名:void showBitGroup64    *
*      参数:二进制数组,数量       *
* 功能:显示指定数组中的指定的元素 *
************************************/
void showBitGroupNum(char *Group,int num){
	int cnt;	
	for(cnt=1;cnt<=num;cnt++){
	//printf("%d:",cnt);
	printf("%c",Group[cnt-1]+48);
	//printf("\t");
	//if(cnt%8==0){printf("\n");}//单个字符换行
	}
	printf("\n");
}

/***********************************
*   函数名:void showSubPassword   *
*            参数:Null            *
*		功能:显示子密钥           *
************************************/
void showSubPassword(){
	int cnt=0;
	for(cnt=0;cnt<16;cnt++){
		showBitGroupNum(K[cnt],48);
	}

}
/***********************************
*      函数名:void leftShift      *
*            参数:NULL            *
*         功能:左移函数           *
************************************/
/处理后的数组,待处理数组,数组元素总数,左移位数
void *leftShift(char *afterTeam,char *team,int cnt,int num){

	int i=0,j=0;
	for(i=0;i<num;i++){
		for(j=0;j<cnt-1;j++){
			afterTeam[j]=team[j+1];
		}
		afterTeam[cnt-1]=team[0];
		for(j=0;j<cnt;j++){
			team[j]=afterTeam[j];
		}
	}
}
/***********************************
*   函数名:void subKeyCalculation *
*            参数:NULL            *
*      功能:子密钥计算函数        *
************************************/
void subKeyCalculation(){
	int cnt=0,count=0;
	for(cnt=0;cnt<16;cnt++){
		
		leftShift(C[cnt+1],C[cnt],28,leftShiftTable[cnt]);
		leftShift(D[cnt+1],D[cnt],28,leftShiftTable[cnt]);
		for(count=0;count<48;count++){
			if(keyComppermTable[count]<29){
				K[cnt][count]=C[cnt+1][keyComppermTable[count]-1];
			}else{
				K[cnt][count]=D[cnt+1][keyComppermTable[count]-29];
			}
			count=count;
		}
	}
}


/***********************************
*   函数名:void password64To56    *
*            参数:Null            *
*功能:对64位密钥压缩至56位并且分组*
************************************/
void password64To56(){
		int cnt=0; 
		for(cnt=0;cnt<28;cnt++)
		{
			//compressPassword[cnt]=passwordbit[passwordCompressTable[cnt]-1];
			C[0][cnt]=passwordbit[passwordCompressTable[cnt]-1];
			D[0][cnt]=passwordbit[passwordCompressTable[cnt+28]-1];
		}
	//	showBitGroupNum(compressPassword,56);
	//	for(cnt=0;cnt<28;cnt++){
	//		C[0][cnt]=compressPassword[cnt];
	//		D[0][cnt]=compressPassword[cnt+28];
	//	}
	//	showBitGroupNum(C[0],28);
	//	showBitGroupNum(D[0],28);
}


/***********************************
*     函数名:void byteToBit       *
*    参数:char *GroupingByte8     *
* 功能:将一个8字节转换成64位二进制*
************************************/
void byteToBit(char *GroupingByte8){
		int Ecin=0,Tcin=0;	
		for(Ecin=0;Ecin<8;Ecin++){
			for(Tcin=0;Tcin<8;Tcin++){
				bitGrouping[Ecin*8+7-Tcin]=(GroupingByte8[Ecin]>>Tcin)&1;
		}
		}
		

}
/***********************************
*   函数名:void passwordToBit64   *
*             参数:NULL           *
*   功能:将password转换成二进制   *
************************************/
void passwordToBit64(){
		int cnt=0;
		byteToBit(password);
		for(cnt=0;cnt<64;cnt++){
			passwordbit[cnt]=bitGrouping[cnt];
		}
}


/***********************************
*函数名:void showPainTestGroupBy64*
*             参数:NULL           *
*      功能:显示分组后的数据      *
************************************/
void showPainTestGroupBy64(){
		int Tcnt=0,Fcnt=0;
	printf("您输入的字符\n");
		for(Tcnt=0;Tcnt<=groupNumber;Tcnt++){
			for(Fcnt=0;Fcnt<8;Fcnt++){
				printf("%c",painTestGroupBy64[Tcnt][Fcnt]);
			}
			printf("\n");
		}
	printf("********\n");
}


/***********************************
*   函数名:void painTestGroupBy   *
*             参数:NULL           *
*   功能:将输入的字符按64位分组   *
************************************/
void painTestGroupBy(){
		int h=0,i=0,j=0;
		for(h=0;h<128;h++){
		for(i=0;i<8;i++){
			painTestGroupBy64[h][i]=painTest[j];
			j++;
		}
		if(painTest[j]==0){
			groupNumber=h;
			return 0; 
		}
		}

}
/***********************************
*函数painTestGroupBy64Transposition*
*参数char*priorTeam,char *afterTeam*
*           功能:IP盒置换         *
************************************/
void painTestGroupBy64Transposition(char *priorTeam,char *afterTeam){
	int cnt=0;
	for(cnt=0;cnt<64;cnt++){
		afterTeam[cnt]=priorTeam[dataInitPermTable[cnt]-1];
	}
}
/***********************************
*   函数名:void feistelIteration  *
*        参数:char *painTest      *
*        功能:feistel计算         *
************************************/
void feistelIteration(char *painTest){
	int cnt=0,count=0;
	char L[17][32]={0};
	char R[17][32]={0};
	char LR[64]={0};
	char E[48]={0};
	char B[8][6]={0};
	char cc[8]={0};
	int i=0,j=0;
	char temp[32]={0};
	char team=0;
	for(cnt=0;cnt<32;cnt++){
		L[0][cnt]=painTest[cnt];
		R[0][cnt]=painTest[cnt+32];
	}

	for(cnt=0;cnt<16;cnt++){

		for(count=0;count<48;count++){
			E[count]=R[cnt][dataExPermTable[count]-1];
			E[count] ^=K[cnt][count];//E(R[i][32])与K[i][48]作异或运算
			B[count/6][count%6]=E[count];//将48位数顺序分成8份,6位一份
		}
		for(count=0;count<8;count++){
			team=dataSBoxTable[count][B[count][0]<<1|B[count][5]][B[count][1]<<3|B[count][2]<<2|B[count][3]<<1|B[count][4]];
			for(i=3,j=0;i>=0;i--,j++){
				temp[count*4+i]=(team>>j)&1;
			}
		}
		for(count=0;count<32;count++){
			R[cnt][count]=temp[dataPermTable[count]-1];
			R[cnt][count]^=L[cnt][count];
			L[cnt+1][count]=R[cnt][count];
		}

	}
	for(count=0;count<64;count++){
		if(dataFTable[count]<32)
		{
			LR[count]=L[16][dataFTable[count]-1];
		}else{
			LR[count]=R[16][dataFTable[count]-33];
		}
	}
	for(cnt=0;cnt<8;cnt++)
		for(count=0;count<8;count++){
			cc[cnt]=cc[cnt]<<1|LR[cnt*8+count];
			ciphertext[cNumber]=LR[cnt*8+count];
			cNumber++;
		}
	printf("%s",cc);
//	showBitGroupNum(LR,64);
//	showBitGroupNum(R[0],32);

}


/***********************************
*      函数名:void encryption     *
*             参数:NULL           *
*           功能:加密函数         *
************************************/
void encryption(){
	int cnt=0;
	for(cnt=0;cnt<=groupNumber;cnt++){
		byteToBit(painTestGroupBy64[cnt]);
		painTestGroupBy64Transposition(bitGrouping,afterTeam);//对当前分组进行IP盒置换,afterTeam为处理完数组。
		feistelIteration(afterTeam);//feistel计算
		//showBitGroupNum(bitGrouping,64);//显示所有待处理分组
	}


}
/***********************************
*     函数名:void ccBase64        *
*             参数:NULL           *
*         功能:密码转换为ba       *
************************************/
void ccBase64(){
	int cnt=0,count=0,ccnetchar=0;
	printf("\n");

	for(cnt=0;cnt<=cNumber/6;cnt++){
		for(count=0;count<6;count++){
			ccnetchar=ccnetchar<<1|ciphertext[cnt*6+count];
		
		}
		printf("%c",Base64[ccnetchar]);
		ccnetchar=0;
	}
	printf("==\n");
}

/***********************************
* 函数名:void passwordProcessing  *
*             参数:NULL           *
*         功能:密码处理函数       *
************************************/
void passwordProcessing(){
	
	printf("请输入密钥:\n");
	gets(password);
	passwordToBit64();
	//showBitGroupNum(passwordbit,64);//显示密码的64位数据	
	password64To56();
	subKeyCalculation();
	//showSubPassword();
}
/***********************************
* 函数名:void painTestProcessing  *
*             参数:NULL           *
*         功能:明文处理函数       *
************************************/
void painTestProcessing(){
	
	printf("请输入明文:\n");
	gets(painTest);
	painTestGroupBy();
	//showPainTestGroupBy64();//显示分组后的字符
	byteToBit(painTestGroupBy64[0]);
	//showBitGroupNum(bitGrouping,64);//显示正在处理的64位数据

}



int main(){

	passwordProcessing();
	painTestProcessing();
	encryption();
	ccBase64();
	return 0;
}
写完之后,测试的加密结果和从在线加密之后的结果都不一样。。。。
这是为什么呢?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值