#include <stdio.h>
#include <string.h>
#include <windows.h>
#include <conio.h>
#include "Schedle.h"//该头文件中包含了DES算法中所使用的全部变换表
class CShift{
public:
DWORDLONG mask[16];
int step[16];
CShift(){
for(int i=0;i<16;i++){
step[i]=2;//其余轮的迭代中,循环左移的位数是2位
mask[i]=0xc000000;
}
step[0]=step[1]=step[8]=step[15]=1;//第1、2、9、16轮迭代中,循环左移的位数是1位
mask[0]=mask[1]=mask[8]=mask[15]=0x8000000;
}
};
class CDES{
public:
CDES(){
m_dwlKey=0;
m_dwlData=0;
ConvertTableToMask(dwlKey_PC_1,64);
ConvertTableToMask(dwlKey_PC_2,56);
ConvertTableToMask(dwlData_IP,64);
ConvertTableToMask(dwlData_Expansion,32);
ConvertTableToMask(dwlData_FP,64);
ConvertTableToMask(dwlData_P,32);
Generate_S();
}
void EncryptKey(char *);
unsigned char* EncryptData(unsigned char *);
unsigned char* DescryptData(unsigned char*);
private:
void ConvertTableToMask(DWORDLONG *,int);
void Generate_S(void);
DWORDLONG ProcessByte(unsigned char*,BOOL);
DWORDLONG PermuteTable(DWORDLONG,DWORDLONG*,int);
void Generate_K(void);
void EncryptKernel(void);
DWORDLONG Generate_B(DWORDLONG,DWORDLONG*);
DWORDLONG dwlData_S[9][4][16];
CShift m_shift;
DWORDLONG m_dwlKey;
DWORDLONG m_dwlData;
DWORDLONG m_dwl_K[17];
};
void CDES::EncryptKey(char *key){//输入种子密钥
printf("\n请输入种子密钥: %s\n",key);
m_dwlKey=ProcessByte((unsigned char*)key,TRUE);
m_dwlKey=PermuteTable(m_dwlKey,dwlKey_PC_1,56);
Generate_K();//16轮的子密钥生成函数
}
void CDES::Generate_K(void){
DWORDLONG C[17],D[17],tmp;
C[0]=m_dwlKey>>28;
D[0]=m_dwlKey&0xfffffff;
for(int i=1;i<=16;i++){
tmp=(C[i-1]&m_shift.mask[i-1])>>(28-m_shift.step[i-1]);
C[i]=((C[i-1]<<m_shift.step[i-1])|tmp)&0x0fffffff;
tmp=(D[i-1]&m_shift.mask[i-1])>>(28-m_shift.step[i-1]);
D[i]=((D[i-1]<<m_shift.step[i-1])|tmp)&0x0fffffff;
m_dwl_K[i]=(C[i]<<28)|D[i];
m_dwl_K[i]=PermuteTable(m_dwl_K[i],dwlKey_PC_2,48);
}
}
DWORDLONG CDES::ProcessByte(unsigned char *key,BOOL shift){//将每1个字符形式的数据转换成8位二进制数据形式
unsigned char tmp;
DWORDLONG byte=0;
int i=0;
while(i<8){
while(*key){
if(byte!=0)
byte<<=8;
tmp=*key;
if(shift)
tmp<<=1;
byte|=tmp;
i++;
key++;
}
if(i<8)
byte<<=8;
i++;
}
return byte;
}
DWORDLONG CDES::PermuteTable(DWORDLONG dwlPara,DWORDLONG* dwlTable,int nDestLen){//置换表函数
int i=0;
DWORDLONG tmp=0,moveBit;
while(i<nDestLen){
moveBit=1;
if(dwlTable[i]&dwlPara){
moveBit<<=nDestLen-i-1;
tmp|=moveBit;
}
i++;
}
return tmp;
}
void CDES::ConvertTableToMask(DWORDLONG *mask,int max){
int i=0;
DWORDLONG nBit=1;
while(mask[i]!=0){
nBit=1;
nBit<<=max-mask[i];
mask[i++]=nBit;
}
}
void CDES::Generate_S(void){//S盒变换
int i;
int j,m,n;
m=n=0;
j=1;
for(i=0;i<512;i++){
dwlData_S[j][m][n]=S_box[i];
n=(n+1)%16;
if(!n){
m=(m+1)%4;
if(!m)
j++;
}
}
}
unsigned char* CDES::EncryptData(unsigned char *block){//加密函数
unsigned char *EncrytedData=new unsigned char(15);
printf("\n输入的明文分组为: %s\n",block);
m_dwlData=ProcessByte(block,0);
m_dwlData=PermuteTable(m_dwlData,dwlData_IP,64);
EncryptKernel();//调用轮函数
DWORDLONG bit6=m_dwlData;
for(int i=0;i<11;i++){
EncrytedData[7-i]=(unsigned char)(bit6&0x3f)+46;
bit6>>=6;
}
EncrytedData[8]='\0';
printf("\n加密后的密文为: %s",EncrytedData);
for(i=0;i<8;i++){
EncrytedData[7-i]=(unsigned char)(m_dwlData&0xff);
m_dwlData>>=8;
}
EncrytedData[8]='\0';
return EncrytedData;
}
void CDES::EncryptKernel(void){ //轮函数
int i=1;
DWORDLONG L[17],R[17],B[9],EK,PSB;
L[0]=m_dwlData>>32;
R[0]=m_dwlData&0xffffffff;
//16轮迭代
for(i=1;i<=16;i++){
L[i]=R[i-1];
R[i-1]=PermuteTable(R[i-1],dwlData_Expansion,48);
EK=R[i-1]^m_dwl_K[i];
PSB=Generate_B(EK,B);//在函数Generate_B(EK,B)中进行了P置换,故PSB=轮函数
R[i]=L[i-1]^PSB;
}
R[16]<<=32;
m_dwlData=R[16]|L[16];
m_dwlData=PermuteTable(m_dwlData,dwlData_FP,64);
}
unsigned char* CDES::DescryptData(unsigned char *desData){//解密算法
int i=1;
unsigned char *DescryptedData=new unsigned char(15);
DWORDLONG L[17],R[17],B[9],EK,PSB;
DWORDLONG dataPara;
dataPara=ProcessByte(desData,0);
dataPara=PermuteTable(dataPara,dwlData_IP,64);
R[16]=dataPara>>32;
L[16]=dataPara&0xffffffff;
for(i=16;i>=1;i--){
R[i-1]=L[i];
L[i]=PermuteTable(L[i],dwlData_Expansion,48);
EK=L[i]^m_dwl_K[i];
PSB=Generate_B(EK,B);
L[i-1]=R[i]^PSB;
}
L[0]<<=32;
dataPara=L[0]|R[0];
dataPara=PermuteTable(dataPara,dwlData_FP,64);
for(i=0;i<8;i++){
DescryptedData[7-i]=(unsigned char)(dataPara&0xff);
dataPara>>=8;
}
DescryptedData[8]='\0';
printf("\n\n解密后的明文为: %s\n",DescryptedData);
return DescryptedData;
}
DWORDLONG CDES::Generate_B(DWORDLONG EKPara,DWORDLONG *block){
int i,m,n;
DWORDLONG tmp=0;
for(i=8;i>0;i--){
block[i]=EKPara&0x3f;
m=(int)(block[i]&0x20)>>4;
m|=block[i]&0x01;
n=(int)(block[i]<<1)>>2;
block[i]=dwlData_S[i][m][n];
EKPara>>=6;
}
for(i=1;i<=8;i++){
tmp|=block[i];
tmp<<=4;
}
tmp>>=4;
tmp=PermuteTable(tmp,dwlData_P,32);//经过P置换得到32位的输出数据
return tmp;
}
void main(void){
CDES des;
des.EncryptKey("12345678");//调用“输入种子密钥”函数,得到初始种子密钥12345678
unsigned char *result=des.EncryptData((unsigned char*)"cipherte");//输入的明文分组为cipherte,调用加密函数EncryptData对其进行加密
des.DescryptData(result);//调用解密函数DescryptData对密文进行解密
}
没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
【用C++6.0可直接使用】 1、DES算法工作的基本原理:DES是基于Feistel密码结构的分组密码,其 入口参数有三个:key、data、mode。 其中,key为加密/解密时使用的 密钥;data为加密/解密的数据;mode为其工作模式:当模式为加密模 式时,明文按照64位进行分组,形成明文分组,此时key用于对数据 加密;当模式为解密模式时,key用于对64位的密文分组进行解密,以 恢复明文。
资源推荐
资源详情
资源评论
收起资源包目录
实验一 对称密钥密码(DES).zip (16个子文件)
实验一 对称密钥密码(DES)
Debug
vc60.pdb 76KB
des.pdb 457KB
vc60.idb 153KB
des.bsc 1.84MB
des.sbr 0B
des.ilk 195KB
des.obj 32KB
des.exe 180KB
des.pch 4.28MB
des.opt 53KB
des.cpp 7KB
des.dsw 531B
des.plg 867B
des.ncb 73KB
des.dsp 3KB
Schedle.h 4KB
共 16 条
- 1
资源评论
- 出来扎道2014-01-07不好,对我用处不大
- wo2cj2013-12-04挺不错的,入门学习一下还是可以的。。
- baifuk1232014-06-13不错,我的编程水平又可以提高了。
- juanwen19875552013-11-19VS2010调下可用, 数组长度为8,大了不知道可用不
hy100100
- 粉丝: 1
- 资源: 6
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功