加密模式:
包含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;
}