原文:http://www.cnblogs.com/erwin/archive/2009/04/14/1435288.html
DES加密解密工具2.1及其代码——支持字符串及文件加密,支持3重DES
作者:尹学渊
版权所有,转载请务必注明出处
一.DES 2.1 说明
最近非常的忙,事情都已经堆着了。所以迟迟没有更新博客,请各位需要代码的朋友谅解,再次给那些给那些最近留言的朋友说一声对不起。
今天我把代码发上来,并再次声明,DES 1.0修正版的代码是正确的,但修正时没有更新DES1.2,所以DES1.2是错误的,希望以后大家不要再问同样的问题。DES 2.x是正确的。
下面我们先看看DES 2.1 的截图:
二. DES 2.1的简介:
1.支持任意长度字符串加密解密
2.明文、密钥可以不足8字节
3.支持回车换行,Tab等特殊字符
4.密文可以选择三种方式显示
5.支持3重DES
6.支持文件加密、解密
7.加密时显示进度
三.DES 算法介绍
关于DES算法的介绍大家可以看我博客里的另一篇文章,[原创]DES算法的介绍以及实现(含上次DES程序1.0的源码),所以在此不在重述。
四. yxyDES2 Class提供的Public函数
下面我们来看看yxyDES2 类(Class)里public函数和它们的用法:
//
功能:产生16个28位的key
//
参数:源8位的字符串(key),存放key的序号0-1
//
结果:函数将调用private CreateSubKey将结果存于char SubKeys[keyN][16][48]
void
InitializeKey(
char
*
srcBytes,unsigned
int
keyN);
//
功能:加密8位字符串
//
参数:8位字符串,使用Key的序号0-1
//
结果:函数将加密后结果存放于private szCiphertext[16]
//
用户通过属性Ciphertext得到
void
EncryptData(
char
*
_srcBytes,unsigned
int
keyN);
//
功能:解密16位十六进制字符串
//
参数:16位十六进制字符串,使用Key的序号0-1
//
结果:函数将解密候结果存放于private szPlaintext[8]
//
用户通过属性Plaintext得到
void
DecryptData(
char
*
_srcBytes,unsigned
int
keyN);
//
功能:加密任意长度字符串
//
参数:任意长度字符串,长度,使用Key的序号0-1
//
结果:函数将加密后结果存放于private szFCiphertextAnyLength[8192]
//
用户通过属性CiphertextAnyLength得到
void
EncryptAnyLength(
char
*
_srcBytes,unsigned
int
_bytesLength,unsigned
int
keyN);
//
功能:解密任意长度十六进制字符串
//
参数:任意长度字符串,长度,使用Key的序号0-1
//
结果:函数将加密后结果存放于private szFPlaintextAnyLength[8192]
//
用户通过属性PlaintextAnyLength得到
void
DecryptAnyLength(
char
*
_srcBytes,unsigned
int
_bytesLength, unsigned
int
keyN);
//
功能:Bytes到Bits的转换,
//
参数:待变换字符串,处理后结果存放缓冲区指针,Bits缓冲区大小
void
Bytes2Bits(
char
*
srcBytes,
char
*
dstBits, unsigned
int
sizeBits);
//
功能:Bits到Bytes的转换,
//
参数:待变换字符串,处理后结果存放缓冲区指针,Bits缓冲区大小
void
Bits2Bytes(
char
*
dstBytes,
char
*
srcBits, unsigned
int
sizeBits);
//
功能:Int到Bits的转换,
//
参数:待变换字符串,处理后结果存放缓冲区指针
void
Int2Bits(unsigned
int
srcByte,
char
*
dstBits);
//
功能:Bits到Hex的转换
//
参数:待变换字符串,处理后结果存放缓冲区指针,Bits缓冲区大小
void
Bits2Hex(
char
*
dstHex,
char
*
srcBits, unsigned
int
sizeBits);
//
功能:Bits到Hex的转换
//
参数:待变换字符串,处理后结果存放缓冲区指针,Bits缓冲区大小
void
Hex2Bits(
char
*
srcHex,
char
*
dstBits, unsigned
int
sizeBits);
//
szCiphertextInBinary的get函数
char
*
GetCiphertextInBinary();
//
szCiphertextInHex的get函数
char
*
GetCiphertextInHex();
//
Ciphertext的get函数
char
*
GetCiphertextInBytes();
//
Plaintext的get函数
char
*
GetPlaintext();
//
CiphertextAnyLength的get函数
char
*
GetCiphertextAnyLength();
//
PlaintextAnyLength的get函数
char
*
GetPlaintextAnyLength();
五. 加密、解密示例
加密时,首先初始化Key,如果是3重DES需要初始化两个Key,InitializeKey函数的第一个参数是char *key,第二个参数含义是指定初始化第几个key,即keyNum:
myDES
->
InitializeKey(szSourceKey1,
0
);
if
(bIs3DES)
{
myDES
->
InitializeKey(szSourceKey2,
1
);
}
初始化完Key以后我们就可以调用加密、解密函数进行相应操作了,以下代码展示了任意长度字符串解密:
myDES
->
InitializeKey(szSourceKey1,
0
);
if
(bIs3DES)
{
myDES
->
InitializeKey(szSourceKey2,
1
);
//
key2
//
D(key0)-E(key1)-D(key0)
myDES
->
DecryptAnyLength(szCiphertextData,ConvertOtherFormat2Ciphertext(strCiphertext.GetBuffer()),
0
);
myDES
->
EncryptAnyLength(myDES
->
GetPlaintextAnyLength(),strlen(myDES
->
GetPlaintextAnyLength()),
1
);
myDES
->
DecryptAnyLength(myDES
->
GetCiphertextAnyLength(),strlen(myDES
->
GetCiphertextAnyLength()),
0
);
}
else
{
//
Decrypt
myDES
->
DecryptAnyLength(szCiphertextData,ConvertOtherFormat2Ciphertext(strCiphertext.GetBuffer()),
0
);
}
六.关于一些特殊情况的特别说明:yxyDES2提供一些转换函数
具体示例我的代码里都有,大家可以下载了看看,对于有特殊要求的朋友来说,比如要用16进制Key,或2进制明文等,大家可以调用yxyDES2 类里的几个相应的转换函数,将其转换成byte,即char *。以下是这几个函数的定义:
//
功能:Bytes到Bits的转换,
//
参数:待变换字符串,处理后结果存放缓冲区指针,Bits缓冲区大小
void
Bytes2Bits(
char
*
srcBytes,
char
*
dstBits, unsigned
int
sizeBits);
//
功能:Bits到Bytes的转换,
//
参数:待变换字符串,处理后结果存放缓冲区指针,Bits缓冲区大小
void
Bits2Bytes(
char
*
dstBytes,
char
*
srcBits, unsigned
int
sizeBits);
//
功能:Int到Bits的转换,
//
参数:待变换字符串,处理后结果存放缓冲区指针
void
Int2Bits(unsigned
int
srcByte,
char
*
dstBits);
//
功能:Bits到Hex的转换
//
参数:待变换字符串,处理后结果存放缓冲区指针,Bits缓冲区大小
void
Bits2Hex(
char
*
dstHex,
char
*
srcBits, unsigned
int
sizeBits);
//
功能:Bits到Hex的转换
//
参数:待变换字符串,处理后结果存放缓冲区指针,Bits缓冲区大小
void
Hex2Bits(
char
*
srcHex,
char
*
dstBits, unsigned
int
sizeBits);
七.关于文件加密
其实文件加密很简单的,类里没有提供,但是调用yxyDES2类里的标准加密函数很容易就搞定了,这是示例:
void
CDESToolDlg::OnBnClickedButtonFileGoE()
{
FILE
*
fpSrc,
*
fpDst;
CString szSrcPath,szDstPath,szKey1,szKey2;
char
buff[
8
]
=
{
0
};
long
fileSize
=
0
, hasDone
=
0
;
edtFileSrc.GetWindowText(szSrcPath);
edtFileDst.GetWindowText(szDstPath);
edtFileKey1.GetWindowText(szKey1);
edtFileKey2.GetWindowText(szKey2);
if
((fpSrc
=
fopen(szSrcPath.GetBuffer(),
"
rb
"
))
==
NULL)
{
MessageBox(
"
打不开源文件!
"
,
"
错误
"
,MB_OK
|
MB_ICONERROR);
return
;
}
if
((fpDst
=
fopen(szDstPath.GetBuffer(),
"
wb
"
))
==
NULL)
{
MessageBox(
"
打不开目的文件!
"
,
"
错误
"
,MB_OK
|
MB_ICONERROR);
return
;
}
fseek(fpSrc,
0
,SEEK_SET);
fseek(fpSrc,
0
,SEEK_END);
fileSize
=
ftell(fpSrc);
rewind(fpSrc);
prcsbar.SetRange(
0
,
100
);
prcsbar.ShowWindow(SW_SHOW);
myDES
->
InitializeKey(szKey1.GetBuffer(),
0
);
if
(chbFileTDES.GetCheck())
{
myDES
->
InitializeKey(szKey2.GetBuffer(),
1
);
while
(
!
feof(fpSrc))
{
memset(buff,
0
,
8
);
fread(buff,
sizeof
(
char
),
8
,fpSrc);
//
E(key0)-D(key1)-E(key0)
myDES
->
EncryptData(buff,
0
);
myDES
->
DecryptData(myDES
->
GetCiphertextInBytes(),
1
);
myDES
->
EncryptData(myDES
->
GetPlaintext(),
0
);
fwrite(myDES
->
GetCiphertextInBytes(),
sizeof
(
char
),
8
,fpDst);
hasDone
+=
8
;
prcsbar.SetPos((
int
)(hasDone
*
100
/
fileSize));
}
}
else
{
while
(
!
feof(fpSrc))
{
memset(buff,
0
,
8
);
fread(buff,
sizeof
(
char
),
8
,fpSrc);
myDES
->
EncryptData(buff,
0
);
fwrite(myDES
->
GetCiphertextInBytes(),
sizeof
(
char
),
8
,fpDst);
hasDone
+=
8
;
prcsbar.SetPos((
int
)(hasDone
*
100
/
fileSize));
}
}
fclose(fpSrc);
fclose(fpDst);
prcsbar.SetPos(
100
);
MessageBox(
"
加密完成!
"
,
"
提示
"
,MB_OK
|
MB_ICONINFORMATION);
prcsbar.ShowWindow(SW_HIDE);
}
八.示例代码下载
我希望大家都读懂程序,并给我提意见,相互进步才是我希望看到的,而不是抄袭。有看不懂程序的朋友,请给我留言。
下载DES Tool 2.1
下载示例工程代码
下载yxyDES2 Class
下载DES Tool 2.1 完整代码(MFC 版 - 编译器:VS 2008)
下载 yxyDES2 (C 语言版)