DES/3DES -- CBC模式 -- 飘云修改版
/************************************************************************/
/*DES、3DES CBC加密解密 */
/*原作者:不详--仍然表示感谢 */
/*修改:飘云(添加 DES CBC模式加密、解密算法) */
/************************************************************************/
#include <windows.h>
enum {ENCRYPT, DECRYPT};
//////////////////////////////////////////////////////////////////////////
// 加/解密 Type—ENCRYPT:加密,DECRYPT:解密
void Des_Run(char Out, char In, bool Type = ENCRYPT);
// 设置密钥
void Des_SetKey(const char Key);
int DESede_CBC_decode(byte *lpIndata, int nlen, byte *lpOutData, byte lpK1, byte lpK2, byte lpK3, byte lpvi);
int DESede_CBC_encode(byte *lpIndata, int nlen, byte *lpOutData, byte lpK1, byte lpK2, byte lpK3, byte lpvi);
// DES算法CBC模式 -- 飘云
int DES_CBC_encode(byte *lpIndata,int nlen, byte *lpOutData, byte lpKey, byte lpIV);
int DES_CBC_decode(byte *lpIndata, int nlen, byte *lpOutData, byte lpKey, byte lpIV);
void DES_encode(byte *lpIndata, int nlen, byte *lpOut, byte *lpkey);
void DES_decode(byte *lpIndata, int nlen, byte *lpOut, byte *lpkey);
//////////////////////////////////////////////////////////////////////////
/************************************************************************/
/*DES、3DES CBC加密解密 */
/*原作者:不详--仍然表示感谢 */
/*修改:飘云(添加 DES CBC模式加密、解密算法) */
/************************************************************************/
#include "3DES.h"
#include <stdio.h>
//////////////////////////////////////////////////////////////////////////
static void F_func(bool In, const bool Ki);// f 函数
static void S_func(bool Out, const bool In);// S 盒代替
static void Transform(bool *Out, bool *In, const char *Table, int len);// 变换
static void Xor(bool *InA, const bool *InB, int len);// 异或
static void RotateL(bool *In, int len, int loop);// 循环左移
static void ByteToBit(bool *Out, const char *In, int bits);// 字节组转换成位组
static void BitToByte(char *Out, const bool *In, int bits);// 位组转换成字节组
//////////////////////////////////////////////////////////////////////////
// initial permutation IP
const static char IP_Table = {
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
};
// final permutation IP^-1
const static char IPR_Table = {
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
};
// expansion operation matrix
static const char E_Table = {
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
};
// 32-bit permutation function P used on the output of the S-boxes
const static char P_Table = {
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
};
// permuted choice table (key)
const static char PC1_Table = {
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
};
// permuted choice key (table)
const static char PC2_Table = {
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
};
// number left rotations of pc1
const static char LOOP_Table = {
1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1
};
// The (in)famous S-boxes
const static char S_Box = {
// 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 bool SubKey; // 16圈子密钥
//////////////////////////////////////////////////////////////////////////
void Des_Run(char Out, char In, bool Type)
{
bool M, Tmp, *Li = &M, *Ri = &M;
ByteToBit(M, In, 64);
Transform(M, M, IP_Table, 64);
if(ENCRYPT != Type)
{
bool M2;
memcpy(M2,M,32);
memcpy(M,M + 32,32);
memcpy(M + 32,M2,32);
}
if( Type == ENCRYPT ){
for(int i=0; i<16; i++) {
memcpy(Tmp, Ri, 32);
F_func(Ri, SubKey);
Xor(Ri, Li, 32);
memcpy(Li, Tmp, 32);
}
}else{
for(int i=15; i>=0; i--) {
memcpy(Tmp, Li, 32);
F_func(Li, SubKey);
Xor(Li, Ri, 32);
memcpy(Ri, Tmp, 32);
}
}
if(ENCRYPT == Type)
{
bool M2;
memcpy(M2,M,32);
memcpy(M,M + 32,32);
memcpy(M + 32,M2,32);
}
Transform(M, M, IPR_Table, 64);
BitToByte(Out, M, 64);
}
void Des_SetKey(const char Key)
{
bool K, *KL = &K, *KR = &K;
unsigned char K2;
ByteToBit((bool*)K2,Key,64);
Transform(K, (bool *)K2, PC1_Table, 56);
for(int i=0; i<16; i++) {
RotateL(KL, 28, LOOP_Table);
RotateL(KR, 28, LOOP_Table);
Transform(SubKey, K, PC2_Table, 48);
}
}
void F_func(bool In, const bool Ki)
{
bool MR;
Transform(MR, In, E_Table, 48);
Xor(MR, Ki, 48);
S_func(In, MR);
Transform(In, In, P_Table, 32);
}
void S_func(bool Out, const bool In)
{
for(char i=0,j,k; i<8; i++,In+=6,Out+=4) {
j = (In<<1) + In;
k = (In<<3) + (In<<2) + (In<<1) + In;
ByteToBit(Out, &S_Box, 4);
}
}
void Transform(bool *Out, bool *In, const char *Table, int len)
{
char Tmp;
for(int i=0; i<len; i++)
Tmp = (char)In[ Table-1 ];
memcpy(Out,(bool*)Tmp, len);
}
void Xor(bool *InA, const bool *InB, int len)
{
for(int i=0; i<len; i++)
InA ^= InB;
}
void RotateL(bool *In, int len, int loop)
{
static bool Tmp;
memcpy(Tmp, In, loop);
memcpy(In, In+loop, len-loop);
memcpy(In+len-loop, Tmp, loop);
}
void ByteToBit(bool *Out, const char *In, int bits)
{
int j = 0;
if( bits / 8)
{
j = 7;
}
else
{
j = 3;
}
for(int i=0; i<bits; i++)
{
Out = (In>>(j - i%8)) & 1;
}
}
void BitToByte(char *Out, const bool *In, int bits)
{
memset(Out, 0, (bits+7)/8);
for(int i=0; i<bits; i++)
{
Out |= In<<(7 - i%8);
}
}
/**************************************************
//
// 函数名称: DES_encode
// 函数功能: 标准DES算法ECB模式加密函数
// 函数参数: lpIndata: 数据
// 函数参数: nlen: 数据的长度
// 函数参数: lpOut: 加密数据
// 函数参数: lpkey: DES算法的Key
// 函数返回值: 无
//
************************************************/
void DES_encode(byte *lpIndata,int nlen,byte *lpOut,byte *lpkey)
{
Des_SetKey((char*)lpkey);
int i = 0;
for(i = 0;i < nlen; i += 8)
{
Des_Run((char*)(lpOut + i),(char*)(lpIndata + i),ENCRYPT);
}
}
/**************************************************
//
// 函数名称: DES_decode
// 函数功能: 标准DES算法ECB模式解密函数
// 函数参数: lpIndata: 密文数据
// 函数参数: nlen: 密文数据的长度
// 函数参数: lpOut: 解密数据
// 函数参数: lpkey: DES算法的Key
// 函数返回值: 无
//
************************************************/
void DES_decode(byte *lpIndata, int nlen, byte *lpOut, byte *lpkey)
{
Des_SetKey((char*)lpkey);
int i = 0;
for(i = 0; i < nlen; i += 8)
{
Des_Run((char*)(lpOut + i), (char*)(lpIndata + i), DECRYPT);
}
}
/**************************************************
//
// 函数名称: DES_CBC_encode
// 函数功能: DES算法CBC模式的加密算法
// 函数参数: lpIndata: 数据
// 函数参数: nlen: 数据的长度
// 函数参数: lpOutData: 加密数据
// 函数参数: lpKey: DES_CBC算法的Key
// 函数参数: lpIV: DES_CBC算法的向量
// 函数返回值: 返回加密后数据的长度
//
************************************************/
int DES_CBC_encode(byte *lpIndata, int nlen, byte *lpOutData, byte lpKey, byte lpIV)
{
byte *data = (byte*)malloc(nlen + 8);
int nFillSize = 8 - nlen % 8;
memcpy(data, lpIndata, nlen);
int i = 0;
int nLoop = nlen / 8 + 1;
for(i = 0; i < nFillSize; i++)
{
data = (byte)nFillSize;
}
byte bytmp = {0};
int j = 0;
for(i = 0; i < 8; i++)
{
bytmp = data ^ lpIV;
}
memcpy(lpOutData, lpIV, 8);
for(i = 0; i < nLoop; i)
{
DES_encode(bytmp, 8, lpOutData + i * 8, lpKey);
for(j = 0; j < 8; j++)
{
bytmp = data[(i + 1) * 8 + j] ^ lpOutData;
}
i++;
}
free(data);
return nLoop * 8;
}
/**************************************************
//
// 函数名称: DES_CBC_decode
// 函数功能: DES算法CBC模式的解密算法
// 函数参数: lpIndata: 密文数据
// 函数参数: nlen: 密文数据的长度
// 函数参数: lpOutData: 解密数据
// 函数参数: lpKey: DES_CBC算法的Key
// 函数参数: lpIV: DES_CBC算法的向量
// 函数返回值: 返回解密后数据的长度
//
************************************************/
int DES_CBC_decode(byte *lpIndata, int nlen, byte *lpOutData, byte lpKey, byte lpIV)
{
int i = 0;
int nLoop = nlen / 8;
byte vi = {0};
int j = 0;
memcpy(vi, lpIV, 8);
for(i = 0; i < nLoop; i)
{
DES_decode(lpIndata + i * 8, 8, lpOutData + i * 8, lpKey);
for(j = 0; j < 8; j++)
{
*(byte*)(lpOutData + i * 8 + j) ^= vi;
}
memcpy(vi, lpIndata + i * 8, 8);
i++;
}
return nlen - lpOutData;
}
/**************************************************
//
// 函数名称: DESede_CBC_encode
// 函数功能: 3DES算法CBC模式的加密算法
// 函数参数: lpIndata: 数据
// 函数参数: nlen: 数据的长度
// 函数参数: lpOutData: 加密数据
// 函数参数: lpk1: 3DES_CBC算法的Key1
// 函数参数: lpk2: 3DES_CBC算法的Key2
// 函数参数: lpk3: 3DES_CBC算法的Key3
// 函数参数: lpvi: 3DES_CBC算法的向量
// 函数返回值: 返回加密后数据的长度
//
************************************************/
int DESede_CBC_encode(byte *lpIndata, int nlen, byte *lpOutData, byte lpK1, byte lpK2, byte lpK3, byte lpIV)
{
byte *data = (byte*)malloc(nlen + 8);
int nFillSize = 8 - nlen % 8;
memcpy(data, lpIndata, nlen);
int i = 0;
int nLoop = nlen / 8 + 1;
for(i = 0; i < nFillSize; i++)
{
data = (byte)nFillSize;
}
byte bytmp = {0};
int j = 0;
for(i = 0; i < 8; i++)
{
bytmp = data ^ lpIV;
}
memcpy(lpOutData,lpIV,8);
for(i = 0; i < nLoop; i)
{
DES_encode(bytmp, 8, data, lpK1);
DES_decode(data, 8, bytmp, lpK2);
DES_encode(bytmp, 8, lpOutData + i * 8, lpK3);
for(j = 0; j < 8; j++)
{
bytmp = data[(i + 1) * 8 + j] ^ lpOutData;
}
i++;
}
free(data);
return nLoop * 8;
}
/**************************************************
//
// 函数名称: DESede_CBC_decode
// 函数功能: 3DES算法CBC模式的解密算法
// 函数参数: lpIndata: 密文数据
// 函数参数: nlen: 密文数据的长度
// 函数参数: lpOutData: 解密数据
// 函数参数: lpk1: 3DES_CBC算法的Key1
// 函数参数: lpk2: 3DES_CBC算法的Key2
// 函数参数: lpk3: 3DES_CBC算法的Key3
// 函数参数: lpvi: 3DES_CBC算法的向量
// 函数返回值: 返回解密后数据的长度
//
************************************************/
int DESede_CBC_decode(byte *lpIndata, int nlen, byte *lpOutData, byte lpK1, byte lpK2, byte lpK3, byte lpvi)
{
int i = 0;
int nLoop = nlen / 8;
byte bytmp = {0};
byte vi = {0};
int j = 0;
memcpy(vi,lpvi,8);
for(i = 0;i < nLoop;i)
{
DES_decode(lpIndata + i * 8, 8, bytmp, lpK1);
DES_encode(bytmp, 8, bytmp, lpK2);
DES_decode(bytmp, 8, lpOutData + i * 8, lpK3);
for(j = 0;j < 8;j++)
{
*(byte*)(lpOutData + i * 8 + j) ^= vi;
}
memcpy(vi,lpIndata + i * 8,8);
i++;
}
return nlen - lpOutData;
}
#include <windows.h>
#include <stdio.h>
#include "3DES.h"
int main(int argc, char* argv[])
{
byte data = {0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11};
byte retdata = {0};
byte desKey = {0x20, 0x73, 0x12, 0x4d, 0x68, 0x59, 0xdd, 0x4c};
byte desIV = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
DES_CBC_encode(data, sizeof(data), retdata, desKey, desIV);
int i = 0;
printf("DES_CBC_encode:\n");
for(i = 0; i < sizeof(retdata); i++)
{
printf("%.2X\n", retdata);
}
ZeroMemory(&data, sizeof(data));
DES_CBC_decode(retdata, sizeof(retdata), data, desKey, desIV);
printf("DES_CBC_decode:\n");
for(i = 0; i < sizeof(data); i++)
{
printf("%.2X\n", data);
}
return 0;
}
{:sweat:}看不懂是啥东东 要是给打个包就更好了{:titter:} 有点看不懂。。。。。。 好东西,....学习了.. 学习学习......... 飘云出品,必属精品! 看不明白,3DES.h 这个文件在哪? 谢谢分享,最近学习密码学 支持一下!!
页:
[1]