c语言 DES加密解密在线单元测试 填充方式

加密模式:

包含DES俩种模式的加密和解密、分别是CBC(加密需要额外指定偏移向量)和ECB模式

填充方式:

PKCS7Padding(PKCS5Padding)填充方式:为.NET和JAVA的默认填充方式,对加密数据字节长度对8取余为r,如r大于0,则补8-r个字节,字节为8-r的值;如果r等于0,则补8个字节8。比如:

加密字符串为为AAA,则补位为AAA55555;加密字符串为BBBBBB,则补位为BBBBBB22;加密字符串为CCCCCCCC,则补位为CCCCCCCC88888888。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int subkeys[16][48];

int IP_Table[64] = {                                     //IP Substitution Matrix
	58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4,
	62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8,
	57, 49, 41, 33, 25, 17,  9, 1, 59, 51, 43, 35, 27, 19, 11, 3,
	61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7 
};
	
int E_Table[48] = {                                    //Extended Matrix 
	32,  1,  2,  3,  4,  5,  4,  5,  6,  7,  8,  9,
	8,  9, 10, 11, 12, 13, 12, 13, 14, 15, 16, 17,
	16, 17, 18, 19, 20, 21, 20, 21, 22, 23, 24, 25,
	24, 25, 26, 27, 28, 29, 28, 29, 30, 31, 32,  1 
};
	
int P_Table[32] = {                                             //  P box  
	16, 7, 20, 21, 29, 12, 28, 17, 1,  15, 23, 26, 5,  18, 31, 10,
	2,  8, 24, 14, 32, 27, 3,  9,  19, 13, 30, 6,  22, 11, 4,  25 
};
	
int IPR_Table[64] = {                                    //Inverse IP Substitution Matrix  
	40, 8, 48, 16, 56, 24, 64, 32, 39, 7, 47, 15, 55, 23, 63, 31,
	38, 6, 46, 14, 54, 22, 62, 30, 37, 5, 45, 13, 53, 21, 61, 29,
	36, 4, 44, 12, 52, 20, 60, 28, 35, 3, 43, 11, 51, 19, 59, 27,
	34, 2, 42, 10, 50, 18, 58, 26, 33, 1, 41,  9, 49, 17, 57, 25
};
	
int PC1_Table[56] = {                               //Key First Substitution Matrix
	57, 49, 41, 33, 25, 17,  9,  1, 58, 50, 42, 34, 26, 18,
	10,  2, 59, 51, 43, 35, 27, 19, 11,  3, 60, 52, 44, 36,
	63, 55, 47, 39, 31, 23, 15,  7, 62, 54, 46, 38, 30, 22,
	14,  6, 61, 53, 45, 37, 29, 21, 13,  5, 28, 20, 12,  4 
};
	
int PC2_Table[48] = {                          // Second Key Substitution Matrix
	14, 17, 11, 24,  1,  5,  3, 28, 15,  6, 21, 10,
	23, 19, 12,  4, 26,  8, 16,  7, 27, 20, 13,  2,
	41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48,
	44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32 
};
	
int S_Box[8][4][16] = {                     //8 S-Box 3-D Array  
											// 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
};

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

static void BitToChar(const int *intput, char *output, int bits)//INT to CHAR  
{
	int i, j;
	
	for (j = 0; j < 8; j++) {
		for (i = 0; i < 8; i++) {
			output[j] = output[j] * 2 + intput[i + 8 * j];
		}
	}
}

static void Xor(int *INA, int *INB, int len)//异或操作  
{
	int i;
	
	for (i = 0; i < len; i++) {
		*(INA + i) = *(INA + i) ^ *(INB + i);
	}
}

static  void IP(const int *input, int *output, int *table)//Initial IP Substitution
{
	int i;
	
	for (i = 0; i < 64; i++) {
		output[i] = input[table[i] - 1];//减1操作不可少!!  
	}
}

static  void E(const int *input, int *output, int *table)//E extend  
{
	int i;
	
	for (i = 0; i < 48; i++) {
		output[i] = input[table[i] - 1];
	}
}

static  void P(const int *input, int *output, int *table)//P substitution  
{
	int i;
	
	for (i = 0; i < 32; i++) {
		output[i] = input[table[i] - 1];
	}
}

static  void IP_In(const int *input, int *output, int *table)//Reverse IP  
{
	int i;
	
	for (i = 0; i < 64; i++) {
		output[i] = input[table[i] - 1];
	}
}

static  void PC_1(const int *input, int *output, int *table)//PC_1  
{
	int i;
	
	for (i = 0; i < 56; i++) {
		output[i] = input[table[i] - 1];
	}
}

static  void PC_2(const int *input, int *output, int *table)//PC_2  
{
	int i;
	
	for (i = 0; i < 48; i++) {
		output[i] = input[table[i] - 1];
	}
}

static  void S(const int *input, int *output)//S-box compression  
{
	int i = 0;
	int j = 0;
	int INT[8];
	
	for (i = 0; i < 48; i = i + 6) {
		INT[j] = S_Box[j][(input[i] << 1) + (input[i + 5])][(input[i + 1] << 3) + (input[i + 2] << 2) + (input[i + 3] << 1) + (input[i + 4])];
		j++;
	}
	
	for (j = 0; j < 8; j++) {
		for (i = 0; i < 4; i++) {
			output[3 * (j + 1) - i + j] = (INT[j] >> i) & 1;
		}
	}
}

static void F_func(int *input, int *output, int *subkey)//Complete DES algorithm wheel transformation
{
	int len = 48;
	int temp[48] = {0};
	int temp_1[32] = {0};
	
	E(input, temp, E_Table);
	Xor(temp, subkey, len);
	S(temp, temp_1);
	P(temp_1, output, P_Table);
}

static void RotateL(const int *input, int *output, int leftCount)//Key Loop Left Shift 
{
	int i;
	int len = 28;
	
	for (i = 0; i < len; i++) {
		output[i] = input[(i + leftCount) % len];
	}
}

static void  subKey_fun(const int *input)//Subkey Generation
{
	int loop = 1;
	int loop_2 = 2;
	int i, j;
	int c[28];
	int d[28];
	int pc_1[56] = {0};
	int pc_2[56] = {0};
	int rotatel_c[28] = {0};
	int rotatel_d[28] = {0};
	int leftCount = 0;
	
	PC_1(input, pc_1, PC1_Table);
	
	
	for (i = 0; i < 28; i++) {
		c[i] = pc_1[i];
		d[i] = pc_1[i + 28];
	}
	
	for (i = 0; i < 16; i++) {
		if (i == 0 || i == 1 || i == 8 || i == 15) {
			leftCount += loop;
			RotateL(c, rotatel_c, leftCount);
			RotateL(d, rotatel_d, leftCount);
		} else {
			leftCount += loop_2;
			RotateL(c, rotatel_c, leftCount);
			RotateL(d, rotatel_d, leftCount);
		}
		
		for (j = 0; j < 28; j++) {
			pc_2[j] = rotatel_c[j];
			pc_2[j + 28] = rotatel_d[j];
		}
	
		PC_2(pc_2, subkeys[i], PC2_Table);
	}
}

static void  DES_Efun(char *input, char *key_in, int *output)
{
	int i, j, k, t;
	int Ip[64] = {0};
	int output_1[64] = {0};
	int chartobit[64] = {0};
	int key[64];
	int l[32];
	int r[32];
	int L[32];
	int R[32];
	
	CharToBit(input, chartobit, 8);
	IP(chartobit, Ip, IP_Table);
	CharToBit(key_in, key, 8);  
	subKey_fun(key);  
	
	for (i = 0; i < 32; i++) {
		l[i] = Ip[i];
		r[i] = Ip[32 + i];
	}
	
	for (j = 1; j < 16; j++) {
		for ( k = 0; k < 32; k++) {
			R[k] = r[k];
			L[k] = R[k];
		}
		F_func(R, r, subkeys[j - 1]);
		Xor(r, l, 32);
		for ( k = 0; k < 32; k++) {
			l[k] = L[k];
		}
	}
	
	for (t = 0; t < 32; t++) {
		R[t] = r[t];
	}
	
	F_func(r, L, subkeys[15]);
	Xor(L, l, 32);
	
	for (t = 0; t < 32; t++) {
		output_1[t] = L[t];
		output_1[32 + t] = R[t];
	}
	
	IP_In(output_1, output, IPR_Table);
}

static void  DES_Dfun(int *input, char *key_in, char *output)
{
	int i, j, k, t;
	int Ip[64] = {0};
	int output_1[64] = {0};
	int output_2[64] = {0};
	int key[64];
	int l[32];
	int r[32];
	int L[32];
	int R[32];
	
	IP(input, Ip, IP_Table);  
	CharToBit(key_in, key, 8);
	subKey_fun(key);  
	
	for ( i = 0; i < 32; i++) {
		l[i] = Ip[i];
		r[i] = Ip[32 + i];
	}
	
	for (j = 1; j < 16; j++) {
		for ( k = 0; k < 32; k++) {
			R[k] = r[k];
			L[k] = R[k];
		}
		F_func(R, r, subkeys[16-j]);
		Xor(r, l, 32);
		for ( k = 0; k < 32; k++) {
			l[k] = L[k];
		}
	}
	
	for (t = 0; t < 32; t++) {
		R[t] = r[t];
	}
	
	F_func(r, L, subkeys[0]);
	Xor(L, l, 32);
	
	for (t = 0; t < 32; t++) {
		output_1[t] = L[t];
		output_1[32 + t] = R[t];
	}
	
	IP_In(output_1, output_2, IPR_Table);
	BitToChar(output_2, output, 8);
}

static void XorWithIv(char* buf, char *iv)
{
  int i;
  
  for(i = 0; i < 8; ++i) {
  		buf[i] ^= iv[i];
  }
}

static int encrypt_ECB(char *src, int srclen, char *dst, char *keyt)
{
	int len = 0;
	int Nl;
	int i,j;
	char input[8];
	int output[64];
	char buf[8];
	char tmp_buff[4096] = {0};

	Nl = srclen/8;

	for (i = 0; i < Nl; i++) {
		for (j = 0; j < 8; j++) {
			input[j] = src[i * 8 + j];
		}

		DES_Efun(input, keyt, output);
		BitToChar(output, buf, 8);
		memcpy(dst + 8 * i, buf, 8);
		len += 8;	
	}
	
	memcpy(tmp_buff, dst, len);
	strcpy(dst,tmp_buff);
	
	return len;
}

static int encrypt_CBC(char *src, int srclen, char *dst, char *keyt, char *iv)
{
	int len = 0;
	int Nl;
	int i,j;
	char input[8];
	int output[64];
	char buf[8];
	char tmp_buff[4096] = {0};

	Nl = srclen/8;

	for (i = 0; i < Nl; i++) {
		for (j = 0; j < 8; j++) {
			input[j] = src[i * 8 + j];
		}

		XorWithIv(input, iv);
		DES_Efun(input, keyt, output);
		BitToChar(output, buf, 8);
		iv = buf;
		memcpy(dst + 8 * i, buf, 8);
		len += 8;	
	}
	memcpy(tmp_buff, dst, len);
	strcpy(dst,tmp_buff);

	return len;
}


static int decrypt_ECB(char *src, int srclen, char *dst, char *keyt)
{
	int len = 0;
	int Nl;
	int i,j;
	char input[8];
	int input_bit[64];
	char output[8];
	char buf[8];
	char tmp_buff[4096] = {0};
	
	Nl = srclen/8;

	for (i = 0; i < Nl; i++) {
		for (j = 0; j < 8; j++) {
			input[j] = src[i * 8 + j];
		}
		
		CharToBit(input, input_bit, 8);
		DES_Dfun(input_bit, keyt, output);
		memcpy(dst + 8 * i, output, 8);
		memcpy(buf, input, 8);
		len += 8;	
	}
	memcpy(tmp_buff, dst, len);
	strcpy(dst,tmp_buff);

	return len;
}

static int decrypt_CBC(char *src, int srclen, char *dst, char *keyt, char *iv)
{
	int len = 0;
	int Nl;
	int i,j;
	char input[8];
	int input_bit[64];
	char output[8];
	char buf[8];
	char tmp_buff[4096] = {0};

	Nl = srclen/8;

	for (i = 0; i < Nl; i++) {
		for (j = 0; j < 8; j++) {
			input[j] = src[i * 8 + j];
		}
		
		CharToBit(input, input_bit, 8);
		DES_Dfun(input_bit, keyt, output);
		XorWithIv(output, iv);
		memcpy(dst + 8 * i, output, 8);
		memcpy(buf, input, 8);
		iv = buf;
		len += 8;	
	}
	memcpy(tmp_buff, dst, len);
	strcpy(dst,tmp_buff);

	return len;
}


int DES_Encryption_ECB(char *plaintext, int plainLen, char *ciphertext, char *keyt)
{
	int len = 0;
	int cover;
	
	cover = 8 - plainLen%8; 
	memset(plaintext+plainLen, cover, cover);
	plainLen += cover;

	len = encrypt_ECB(plaintext, plainLen, ciphertext, keyt);

	return len;
}

int DES_Encryption_CBC(char *plaintext, int plainLen, char *ciphertext, char *keyt, char *iv)
{
	int len = 0;
	int cover;

	cover = 8 - plainLen%8; 
	memset(plaintext+plainLen, cover, cover);
	plainLen += cover;

	len = encrypt_CBC(plaintext, plainLen, ciphertext, keyt, iv);

	return len;
}


int DES_Decryption_ECB(char *ciphertext, int cipherLen, char *plaintext, char *keyt)
{
	int len = 0;
	int i, j = 0;
	int buIndex;

	len = decrypt_ECB(ciphertext, cipherLen, plaintext, keyt);

	buIndex = plaintext[len-1];
	
	if (buIndex >= 1 && buIndex <= 8) {
		for (i=0; i<buIndex; i++) {
			if (plaintext[len-i-1] == buIndex && plaintext[len-i-1] >= 1 && plaintext[len-i-1] <= 8) {
				j++;
			}
		}

		if (j == buIndex) {
			len -= buIndex;
		}
	}
	
	return len;
}

int DES_Decryption_CBC(char *ciphertext, int cipherLen, char *plaintext, char *keyt, char *iv)
{
	int len = 0;
	int i, j = 0;
	int buIndex;
	
	len = decrypt_CBC(ciphertext, cipherLen, plaintext, keyt, iv);

	buIndex = plaintext[len-1];
	
	if (buIndex >= 1 && buIndex <= 8) {
		for (i = 0; i < buIndex; i++) {
			if (plaintext[len-i-1] == buIndex && plaintext[len-i-1] >= 1 && plaintext[len-i-1] <= 8) {
				j++;
			}
		}

		if (j == buIndex) {
			len -= buIndex;
		}
	}
	
	return len;
}

void hex_data_to_log_data(char *src, int len, char *dst)
{
	int i = 0;
	int index = 0;
	char buff[1024] = {0};
	for (i = 0; i < len; i++) {
	    index += sprintf(buff + index, "%02x", src[i]);
	    if (i != len - 1)
			index += sprintf(buff + index, " ");
	}
	if (strlen(buff) > 0)
		strcpy(dst, buff);
}

void print_hex_data(char *modbus_cmd, int len, char *title)
{
	char log_modbus_data[1024] = {0};
	int size = len;
	int offset = 0;
	int print_len = 0;
	int count = 0;
	int max_len = 60;
	
	if (size <= max_len) {
		hex_data_to_log_data(modbus_cmd, size, log_modbus_data);
		if (strlen(log_modbus_data) > 0)
			printf("%s:%s", title, log_modbus_data);
	} else {
		while (size > 0) {
			count++;
			if (size > max_len)
				print_len = max_len;
			else
				print_len = size;
			
			hex_data_to_log_data(modbus_cmd + offset, print_len, log_modbus_data);
			if (strlen(log_modbus_data) > 0)
				printf("%s-%d:%s", title, count, log_modbus_data);
			offset += print_len;
			size -= print_len;
		}
	}
}

int main(void) { 
    int len;
	char key[32] = "abc_123" ;
	char iv[8] = {0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08};
	char plaintext[1024] = "123456";
	char encrypted_buff[1024] = {0};
	
	char buff[1024] = {0};
	char tmp_buff[1024] = {0};
	len = DES_Encryption_ECB(plaintext, 100, encrypted_buff, key);
	len = DES_Decryption_ECB(encrypted_buff, len, buff, key);
	//memcpy(tmp_buff, buff, len);
	//strcpy(buff,tmp_buff);
	//printf("[%s],[%s]\n",encrypted_buff,buff);
	
	//len = DES_Encryption_CBC(plaintext, strlen(plaintext), encrypted_buff, key, iv);
	//len = DES_Decryption_CBC(encrypted_buff, len, buff, key, iv);
	memcpy(tmp_buff, buff, len);
	strcpy(buff,tmp_buff);
	//print_hex_data(encrypted_buff,strlen(encrypted_buff),"15353");
	printf("[%s],[%s]",encrypted_buff,buff);
	
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值