博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
加密算法之DES
阅读量:5374 次
发布时间:2019-06-15

本文共 7948 字,大约阅读时间需要 26 分钟。

// MatchTwoArray.cpp : 定义控制台应用程序的入口点。

//

#include "stdafx.h"

#include<iostream>
#include<stdio.h>
#include<iomanip>
#include<string>
using namespace std;

enum {ENCRYPTION,DECRYPTION};
bool Using_DES(char *Out,char *In,long textlen,int keylen,const char *Key,bool Type = ENCRYPTION);

// 初始置换(initial permutation)IP列表
const 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, 7
};

// 扩展置换(expansion operation)E列表

static 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
};

//密钥置换PC1列表

const static char PC1_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
};

// 密钥置换中每轮移动的位数
const static char LOOP_TABLE[16] = {
1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1
};

// 压缩置换PC2列表
const static char PC2_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
};

// S-盒代替(substitution box)

const static char S_BOX[8][4][16] = {
// S盒1
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,
// S盒2
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,
// S盒3
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,
// S盒4
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,
// S盒5
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,
// S盒6
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,
// S盒7
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,
// S盒8
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
};
// P-盒置换(straight permutation )或称为直接置换
const 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
};
// 末置换(final permutation)IP^-1列表
const static char IPF_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
};
//-----------------------------------------------------------------------------------
typedef bool (*SUBKEY_P)[16][48];
//-----------------------------------------------------------------------------------
static void DES(char Out[8], char In[8], const SUBKEY_P pskey, bool Type);//标准DES加/解密
static void SETKEY(const char* Key, int len);// 设置密钥
static void Set_SubKey(SUBKEY_P pskey, const char Key[8]);// 设置子密钥
static void F_FUNCTION(bool In[32], const bool Ki[48]);// f 函数完成扩展置换、S-盒代替和P盒置换
static void S_BOXF(bool Out[32], const bool In[48]);// 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 CYCLELEFT(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);// 位组转换成字节组函数
//-----------------------------------------------------------------------------------
static bool SubKey[1][16][48];// 子密钥
static char T[256], deskey[16];
//-----------------------------------------------------------------------------------
//以下是各个函数的定义
//-----------------------------------------------------------------------------------
//加密/解密函数
//
bool Using_DES(char *Out, char *In, long textlen, int keylen,const char *Key, bool Type)
{
if( !( Out && In && Key && (textlen=(textlen+7)&0xfffffff8) ) )
return false;
SETKEY(Key, keylen);
for(long i=0,j=textlen>>3; i<j; ++i,Out+=8,In+=8)
DES(Out, In, &SubKey[0], Type); // 1次DES
return true;
}
void ByteToBit(bool *Out, const char *In, int bits)
{
for(int i=0; i<bits; ++i)
Out[i] = (In[i>>3]>>(i&7)) & 1;
}

// 字节组转换成位组函数

void BitToByte(char *Out, const bool *In, int bits)
{
memset(Out, 0, bits>>3);
for(int i=0; i<bits; ++i)
Out[i>>3] |= In[i]<<(i&7);
}

// 循环左移函数

void CYCLELEFT(bool *In, int len, int loop)
{
memcpy(T, In, loop);
memcpy(In, In+loop, len-loop);
memcpy(In+len-loop, T, loop);
}

// 设置子密钥

void Set_SubKey(SUBKEY_P pskey, const char Key[8])
{
static bool K[64], *KL=&K[0], *KR=&K[28];
ByteToBit(K, Key, 64);
TRANSFORM(K, K, PC1_TABLE, 56);
for(int i=0; i<16; ++i)
{
CYCLELEFT(KL, 28, LOOP_TABLE[i]);
CYCLELEFT(KR, 28, LOOP_TABLE[i]);
TRANSFORM((*pskey)[i], K, PC2_TABLE, 48);
}
}

// 设置密钥

void SETKEY(const char* Key, int len)
{
memset(deskey, 0, 24);
memcpy(deskey, Key, len>24?24:len);
Set_SubKey(&SubKey[0], &deskey[0]);
}
void S_BOXF(bool Out[32], const bool In[48])
{
for(char i=0,j,k; i<8; ++i,In+=6,Out+=4)
{
j = (In[0]<<1) + In[5];
k = (In[1]<<3) + (In[2]<<2) + (In[3]<<1) + In[4];
ByteToBit(Out, &S_BOX[i][j][k], 4);
}
}

// f 函数完成扩展置换、S-盒代替和P盒置换

void F_FUNCTION(bool In[32], const bool Ki[48])
{
static bool MR[48];
TRANSFORM(MR, In, E_TABLE, 48);
XOR(MR, Ki, 48);
S_BOXF(In, MR);
TRANSFORM(In, In, P_TABLE, 32);
}
// 变换函数
void TRANSFORM(bool *Out, bool *In, const char *Table, int len)
{
for(int i=0; i<len; ++i)
T[i] = In[ Table[i]-1 ];
memcpy(Out, T, len);
}
void XOR(bool *InA, const bool *InB, int len)
{
for(int i=0; i<len; ++i)
InA[i] ^= InB[i];
}

//标准DES加/解密

void DES(char Out[8], char In[8], const SUBKEY_P pskey, bool Type)
{
static bool M[64], tmp[32], *Li=&M[0], *Ri=&M[32];
ByteToBit(M, In, 64);
TRANSFORM(M, M, IP_TABLE, 64);
if( Type == ENCRYPTION )
{
for(int i=0; i<16; ++i)
{
memcpy(tmp, Ri, 32);
F_FUNCTION(Ri, (*pskey)[i]);
XOR(Ri, Li, 32);
memcpy(Li, tmp, 32);
}
}
else
{
for(int i=15; i>=0; --i)
{
memcpy(tmp, Li, 32);
F_FUNCTION(Li, (*pskey)[i]);
XOR(Li, Ri, 32);
memcpy(Ri, tmp, 32);
}
}
TRANSFORM(M, M, IPF_TABLE, 64);
BitToByte(Out, M, 64);
}

void main()
{
char text[]="The Test of DES !\n"
"姓名:许同学学号:0123456789\n"
"华中科技大学\n"
"合肥电大站\n"
"Email: abc@.com\n"
"Tel:027-0000000";

char key[]="Tddfdf ",buf[255];

memset(buf, 0, sizeof(buf));
strcpy(buf, text);
puts("\n加密前文本:");
puts(buf);
printf("加密前文本长度:%d\n",sizeof(text));
puts("\n密钥:");
puts(key);
printf("密钥文本长度:%d\n",sizeof(key));
Using_DES(buf, buf, sizeof(text), sizeof(key), key, ENCRYPTION);
puts("\n加密后:");
puts(buf);
Using_DES(buf, buf, sizeof(text),sizeof(key), key, DECRYPTION);
puts("\n解密后文本:");
puts(buf);
getchar();
}

 

 

 

 

 
 
  
 
 
 
 
  

转载于:https://www.cnblogs.com/hustxgm/archive/2013/03/11/2954605.html

你可能感兴趣的文章
JavaScript 技巧与高级特性
查看>>
Uva 11729 Commando War
查看>>
增强学习(一) ----- 基本概念
查看>>
ubuntu下USB连接Android手机
查看>>
C# 语句 分支语句 switch----case----.
查看>>
反射获取 obj类 的属性 与对应值
查看>>
表单中的readonly与disable的区别(zhuan)
查看>>
win10下安装配置mysql-8.0.13--实战可用
查看>>
周记2018.8.27~9.2
查看>>
MySQL中 1305-FUNCTION liangshanhero2.getdate does not exit 问题解决
查看>>
python序列化和json
查看>>
mongodb
查看>>
SSH-struts2的异常处理
查看>>
《30天自制操作系统》学习笔记--第14天
查看>>
LGPL协议的理解
查看>>
1、Python基础
查看>>
Unity The Tag Attribute Matching Rule
查看>>
试着理解下kvm
查看>>
WebService学习总结(二)--使用JDK开发WebService
查看>>
Tizen参考手机RD-210和RD-PQ
查看>>