主题:DES算法!
lanjingquan
[专家分:510] 发布于 2003-09-21 12:47:00
现在网上的DES加密算法大都有问题,有幸在BBS上找到一个,但接口不够好。下面这一个是用MFC的CSTRING封装了一次的。
下面这两个是关键
---------------------------------------
CString SEncrypt(CString);
CString SDecrypt(CString);
---------------------------------------
int main()
{
CString aa,bb,cc;
aa = "kingwind";
unsigned long s1,s2;
s1 = 30;
s2 = 100;
CPackage_Encoder coder1,coder2;
const char k1[256]="dsa3425Hello";
coder1.SetKey(k1);
coder2.SetKey(k1);
cout<<"明文:"<<aa<<endl;
bb = coder1.SEncrypt(aa);
cout<<"密文:"<<bb<<endl;
cc = coder2.SDecrypt(bb);
cout<<"明文:"<<cc<<endl;
return 0;
};
回复列表 (共13个回复)
沙发
lanjingquan [专家分:510] 发布于 2003-09-21 12:41:00
// DesCode.h: interface for the CDesCode class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_DESCODE_H__C03E92C7_2754_4B05_B19D_59D86587C26D__INCLUDED_)
#define AFX_DESCODE_H__C03E92C7_2754_4B05_B19D_59D86587C26D__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "AFX.h"
typedef union{
unsigned char byte[8];
struct
{
unsigned long low;
unsigned long high;
}dword;
}SBitBlock;
//static
extern void deskey (unsigned char const *key, int decryptf, unsigned long *outbuf);
//static
extern void desDES (unsigned char const inblock[8], unsigned char outblock[8], unsigned long const *keys);
class CDES_Encoder
{
private:
// Data:16 48-bit k[i], calculated from "key", use low 6-bit in each byte
SBitBlock encrypt_k[16],decrypt_k[16];
public:
// Functions:SetKey,Encrypt,Decrypt
inline void SetKey(const SBitBlock& key); //calculate k[i]
inline void Encrypt(SBitBlock& destination, const SBitBlock& source)const;
inline void Decrypt(SBitBlock& destination, const SBitBlock& source)const;
};
inline void CDES_Encoder::SetKey(const SBitBlock& key)
{
deskey((unsigned char const*)(&key),0,(unsigned long*)encrypt_k);
deskey((unsigned char const*)(&key),1,(unsigned long*)decrypt_k);
};
inline void CDES_Encoder::Encrypt(SBitBlock& destination, const SBitBlock& source)const
{
desDES((unsigned char const*)(&source),(unsigned char*)(&destination),(unsigned long const*)encrypt_k);
};
inline void CDES_Encoder::Decrypt(SBitBlock& destination, const SBitBlock& source)const
{
desDES((unsigned char const*)(&source),(unsigned char*)(&destination),(unsigned long const*)decrypt_k);
};
// Below defines the package encryption and decryption class
class CPackage_Encoder{
private:
// Data: a DES coder and package seed
CDES_Encoder theDEScoder;
SBitBlock seed;
public:
// Functions: SetKey,SetSeed,GetSeed,Encrypt,Decrypt
void SetKey(const char* password);
inline void SetSeed(unsigned long lo,unsigned long hi);
inline void GetSeed(unsigned long& lo,unsigned long& hi)const;
CString SEncrypt(CString);
CString SDecrypt(CString);
int Encrypt(unsigned char destination[],const unsigned char source[], unsigned sourcesize)const;
int Decrypt(unsigned char destination[],const unsigned char source[], unsigned sourcesize);
};
inline void CPackage_Encoder::SetSeed(unsigned long lo,unsigned long hi)
{
seed.dword.low=lo;
seed.dword.high=hi;
};
inline void CPackage_Encoder::GetSeed(unsigned long& lo,unsigned long& hi)const
{
lo=seed.dword.low;
hi=seed.dword.high;
};
#endif // !defined(AFX_DESCODE_H__C03E92C7_2754_4B05_B19D_59D86587C26D__INCLUDED_)
板凳
lanjingquan [专家分:510] 发布于 2003-09-21 12:42:00
// DesCode.cpp: implementation of the CDesCode class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "hotel.h"
#include "DesCode.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
#define word32 unsigned long
#define byte unsigned char
extern void deskey (unsigned char const *key, int decryptf, unsigned long *outbuf);
extern void desDES (unsigned char const inblock[8], unsigned char outblock[8], unsigned long const *keys);
/* The size of a scheduled DES key */
#define DES_KEYWORDS 32
#define DES_KEYBYTES (sizeof(word32)*DES_KEYWORDS)
static word32 const bigbyte[24] = {
0x800000L, 0x400000L, 0x200000L, 0x100000L,
0x80000L, 0x40000L, 0x20000L, 0x10000L,
0x8000L, 0x4000L, 0x2000L, 0x1000L,
0x800L, 0x400L, 0x200L, 0x100L,
0x80L, 0x40L, 0x20L, 0x10L,
0x8L, 0x4L, 0x2L, 0x1L };
/* Use the key schedule specified in the Standard (ANSI X3.92-1981). */
static byte const pc1[56] = {
56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17,
9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35,
62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21,
13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3 };
static byte const totrot[16] = {
1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28 };
static byte const pc2[48] = {
13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9,
22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1,
40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47,
43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31 };
/*
* This is a less-that-brilliant key scheduling routine.
* It could stand optimization some time.
*
* cookey "cooks" the key into the desired form, from the basic one that
* has the keys for S-boxes 1 through 8 in adjacent words of the
* "raw" array. I.e. the bits start out like this:
* xxxxxxxx111111222222333333444444
* xxxxxxxx555555666666777777888888
* We actually want the keys to look like this:
* 111111xx333333xx555555xx777777xx
* 222222xx444444xx666666xx888888xx
* Where the "xx" patterns are set to 01020300 for use by the s-box
* lookup code in the main encrypt loop.
*/
static void
cookey (word32 *raw, word32 *cooked)
{
int i;
for (i = 0; i < 16; i++, raw += 2, cooked += 2) {
cooked[0] = (raw[0] & 0x00fc0000L) << 8;
cooked[0] |= (raw[0] & 0x00000fc0L) << 12;
cooked[0] |= (raw[1] & 0x00fc0000L) >> 8;
cooked[0] |= (raw[1] & 0x00000fc0L) >> 4;
cooked[0] |= 0x01020300;
cooked[1] = (raw[0] & 0x0003f000L) << 14;
cooked[1] |= (raw[0] & 0x0000003fL) << 18;
cooked[1] |= (raw[1] & 0x0003f000L) >> 2;
cooked[1] |= (raw[1] & 0x0000003fL) << 2;
cooked[1] |= 0x01020300;
}
return;
}
void deskey (byte const *key, int decryptf, word32 *outbuf)
{
int i, j, l, m, n;
byte pc1m[56], pcr[56];
word32 kn[32];
for (j = 0; j < 56; j++) {
l = pc1[j];
m = l & 07;
pc1m[j] = ( key[l >> 3] >> (~l & 7) ) & 1;
}
for (i = 0; i < 16; i++ ) {
m = (decryptf ? 15-i : i) << 1;
n = m + 1;
kn[m] = kn[n] = 0L;
for (j = 0; j < 28; j++) {
l = j + totrot[i];
if (l >= 28)
l -= 28;
pcr[j] = pc1m[l];
}
for (j = 28; j < 56; j++) {
l = j + totrot[i];
if (l >= 56)
l -= 28;
pcr[j] = pc1m[l];
}
for (j = 0; j < 24; j++) {
if (pcr[pc2[j]])
kn[m] |= bigbyte[j];
if (pcr[pc2[j+24]])
kn[n] |= bigbyte[j];
}
}
cookey(kn, outbuf);
return;
}
/* S-boxes 1, 3, 5, 7, plus P permutation, rotated */
static word32 const SP0[512] = {
0x00404100, 0x00000000, 0x00004000, 0x00404101,
0x00404001, 0x00004101, 0x00000001, 0x00004000,
0x00000100, 0x00404100, 0x00404101, 0x00000100,
0x00400101, 0x00404001, 0x00400000, 0x00000001,
0x00000101, 0x00400100, 0x00400100, 0x00004100,
0x00004100, 0x00404000, 0x00404000, 0x00400101,
0x00004001, 0x00400001, 0x00400001, 0x00004001,
0x00000000, 0x00000101, 0x00004101, 0x00400000,
0x00004000, 0x00404101, 0x00000001, 0x00404000,
0x00404100, 0x00400000, 0x00400000, 0x00000100,
0x00404001, 0x00004000, 0x00004100, 0x00400001,
0x00000100, 0x00000001, 0x00400101, 0x00004101,
0x00404101, 0x00004001, 0x00404000, 0x00400101,
0x00400001, 0x00000101, 0x00004101, 0x00404100,
0x00000101, 0x00400100, 0x00400100, 0x00000000,
0x00004001, 0x00004100, 0x00000000, 0x00404001,
0x00000082, 0x02008080, 0x00000000, 0x02008002,
0x02000080, 0x00000000, 0x00008082, 0x02000080,
0x00008002, 0x02000002, 0x02000002, 0x00008000,
0x02008082, 0x00008002, 0x02008000, 0x00000082,
0x02000000, 0x00000002, 0x02008080, 0x00000080,
0x00008080, 0x02008000, 0x02008002, 0x00008082,
0x02000082, 0x00008080, 0x00008000, 0x02000082,
0x00000002, 0x02008082, 0x00000080, 0x02000000,
0x02008080, 0x02000000, 0x00008002, 0x00000082,
0x00008000, 0x02008080, 0x02000080, 0x00000000,
0x00000080, 0x00008002, 0x02008082, 0x02000080,
0x02000002, 0x00000080, 0x00000000, 0x02008002,
0x02000082, 0x00008000, 0x02000000, 0x02008082,
0x00000002, 0x00008082, 0x00008080, 0x02000002,
0x02008000, 0x02000082, 0x00000082, 0x02008000,
0x00008082, 0x00000002, 0x02008002, 0x00008080,
0x00000040, 0x00820040, 0x00820000, 0x10800040,
0x00020000, 0x00000040, 0x10000000, 0x00820000,
0x10020040, 0x00020000, 0x00800040, 0x10020040,
0x10800040, 0x10820000, 0x00020040, 0x10000000,
0x00800000, 0x10020000, 0x10020000, 0x00000000,
0x10000040, 0x10820040, 0x10820040, 0x00800040,
0x10820000, 0x10000040, 0x00000000, 0x10800000,
0x00820040, 0x00800000, 0x10800000, 0x00020040,
0x00020000, 0x10800040, 0x00000040, 0x00800000,
0x10000000, 0x00820000, 0x10800040, 0x10020040,
0x00800040, 0x10000000, 0x10820000, 0x00820040,
0x10020040, 0x00000040, 0x00800000, 0x10820000,
0x10820040, 0x00020040, 0x10800000, 0x10820040,
0x00820000, 0x00000000, 0x10020000, 0x10800000,
0x00020040, 0x00800040, 0x10000040, 0x00020000,
0x00000000, 0x10020000, 0x00820040, 0x10000040,
0x00080000, 0x81080000, 0x81000200, 0x00000000,
0x00000200, 0x81000200, 0x80080200, 0x01080200,
0x81080200, 0x00080000, 0x00000000, 0x81000000,
0x80000000, 0x01000000, 0x81080000, 0x80000200,
0x01000200, 0x80080200, 0x80080000, 0x01000200,
0x81000000, 0x01080000, 0x01080200, 0x80080000,
0x01080000, 0x00000200, 0x80000200, 0x81080200,
0x00080200, 0x80000000, 0x01000000, 0x00080200,
0x01000000, 0x00080200, 0x00080000, 0x81000200,
0x81000200, 0x81080000, 0x81080000, 0x80000000,
0x80080000, 0x01000000, 0x01000200, 0x00080000,
0x01080200, 0x80000200, 0x80080200, 0x01080200,
0x80000200, 0x81000000, 0x81080200, 0x01080000,
0x00080200, 0x00000000, 0x80000000, 0x81080200,
0x00000000, 0x80080200, 0x01080000, 0x00000200,
0x81000000, 0x01000200, 0x00000200, 0x80080000 };
/* S-boxes 2, 4, 6, 8, plus P permutation, rotated */
static word32 const SP1[512] = {
0x20042008, 0x20002000, 0x00002000, 0x00042008,
0x00040000, 0x00000008, 0x20040008, 0x20002008,
0x20000008, 0x20042008, 0x20042000, 0x20000000,
0x20002000, 0x00040000, 0x00000008, 0x20040008,
0x00042000, 0x00040008, 0x20002008, 0x00000000,
0x20000000, 0x00002000, 0x00042008, 0x20040000,
0x00040008, 0x20000008, 0x00000000, 0x00042000,
0x00002008, 0x20042000, 0x20040000, 0x00002008,
0x00000000, 0x00042008, 0x20040008, 0x00040000,
0x20002008, 0x20040000, 0x20042000, 0x00002000,
0x20040000, 0x20002000, 0x00000008, 0x20042008,
0x00042008, 0x00000008, 0x00002000, 0x20000000,
0x00002008, 0x20042000, 0x00040000, 0x20000008,
0x00040008, 0x20002008, 0x20000008, 0x00040008,
0x00042000, 0x00000000, 0x20002000, 0x00002008,
0x20000000, 0x20040008, 0x20042008, 0x00042000,
0x40200800, 0x40000820, 0x40000820, 0x00000020,
0x00200820, 0x40200020, 0x40200000, 0x40000800,
0x00000000, 0x00200800, 0x00200800, 0x40200820,
0x40000020, 0x00000000, 0x00200020, 0x40200000,
0x40000000, 0x00000800, 0x00200000, 0x40200800,
0x00000020, 0x00200000, 0x40000800, 0x00000820,
0x40200020, 0x40000000, 0x00000820, 0x00200020,
0x00000800, 0x00200820, 0x40200820, 0x40000020,
0x00200020, 0x40200000, 0x00200800, 0x40200820,
0x40000020, 0x00000000, 0x00000000, 0x00200800,
0x00000820, 0x00200020, 0x40200020, 0x40000000,
0x40200800, 0x40000820, 0x40000820, 0x00000020,
0x40200820, 0x40000020, 0x40000000, 0x00000800,
0x40200000, 0x40000800, 0x00200820, 0x40200020,
0x40000800, 0x00000820, 0x00200000, 0x40200800,
0x00000020, 0x00200000, 0x00000800, 0x00200820,
0x08000004, 0x08100000, 0x00001000, 0x08101004,
0x08100000, 0x00000004, 0x08101004, 0x00100000,
0x08001000, 0x00101004, 0x00100000, 0x08000004,
0x00100004, 0x08001000, 0x08000000, 0x00001004,
0x00000000, 0x00100004, 0x08001004, 0x00001000,
0x00101000, 0x08001004, 0x00000004, 0x08100004,
0x08100004, 0x00000000, 0x00101004, 0x08101000,
0x00001004, 0x00101000, 0x08101000, 0x08000000,
0x08001000, 0x00000004, 0x08100004, 0x00101000,
0x08101004, 0x00100000, 0x00001004, 0x08000004,
0x00100000, 0x08001000, 0x08000000, 0x00001004,
0x08000004, 0x08101004, 0x00101000, 0x08100000,
0x00101004, 0x08101000, 0x00000000, 0x08100004,
0x00000004, 0x00001000, 0x08100000, 0x00101004,
0x00001000, 0x00100004, 0x08001004, 0x00000000,
0x08101000, 0x08000000, 0x00100004, 0x08001004,
0x04000410, 0x00000400, 0x00010000, 0x04010410,
0x04000000, 0x04000410, 0x00000010, 0x04000000,
0x00010010, 0x04010000, 0x04010410, 0x00010400,
0x04010400, 0x00010410, 0x00000400, 0x00000010,
0x04010000, 0x04000010, 0x04000400, 0x00000410,
0x00010400, 0x00010010, 0x04010010, 0x04010400,
0x00000410, 0x00000000, 0x00000000, 0x04010010,
0x04000010, 0x04000400, 0x00010410, 0x00010000,
0x00010410, 0x00010000, 0x04010400, 0x00000400,
0x00000010, 0x04010010, 0x00000400, 0x00010410,
0x04000400, 0x00000010, 0x04000010, 0x04010000,
0x04010010, 0x04000000, 0x00010000, 0x04000410,
0x00000000, 0x04010410, 0x00010010, 0x04000010,
0x04010000, 0x04000400, 0x04000410, 0x00000000,
0x04010410, 0x00010400, 0x00010400, 0x00000410,
0x00000410, 0x00010010, 0x04000000, 0x04010400 };
/*
* This encryption function is fairly clever in the way it does its
* s-box lookup. The S-boxes are indexed by bytes, rather than
* words, because that's faster on many machines, and shifting
* everything two bits to do the multiply by 4 is trivial.
* Then, the indexing into the various S boxes is done by
* adding the appropriate offset bits into the key array, so the
* addition is done by the XOR with the key rather than having to
* be done explicitly here.
*/
void desDES (byte const inblock[8], byte outblock[8], word32 const *keys)
{
word32 s, t, right, leftt;
int round;
leftt = ((word32)inblock[0] << 24)
| ((word32)inblock[1] << 16)
| ((word32)inblock[2] << 8)
| (word32)inblock[3];
right = ((word32)inblock[4] << 24)
| ((word32)inblock[5] << 16)
| ((word32)inblock[6] << 8)
| (word32)inblock[7];
/* Initial permutation IP */
t = ((leftt >> 4) ^ right) & 0x0f0f0f0fL;
right ^= t;
leftt ^= (t << 4);
t = ((leftt >> 16) ^ right) & 0x0000ffffL;
right ^= t;
leftt ^= (t << 16);
t = ((right >> 2) ^ leftt) & 0x33333333L;
leftt ^= t;
right ^= (t << 2);
t = ((right >> 8) ^ leftt) & 0x00ff00ffL;
leftt ^= t;
right ^= (t << 8);
leftt = ((leftt >> 1) | (leftt << 31));
t = (leftt ^ right) & 0x55555555L;
leftt ^= t;
right ^= t;
right = ((right >> 1) | (right << 31));
for (round = 0; round < 8; round++) {
s = (right & 0xfcfcfcfc) ^ keys[0];
t = (((right >> 28) | (right << 4)) & 0xfcfcfcfc)
^ keys[1];
leftt ^= *(word32 *)((char *)SP0+( s & 0x3fc))
^ *(word32 *)((char *)SP0+((s >> 8 ) & 0x3fc))
^ *(word32 *)((char *)SP0+((s >> 16) & 0x3fc))
^ *(word32 *)((char *)SP0+((s >> 24) & 0x0fc))
^ *(word32 *)((char *)SP1+( t & 0x3fc))
^ *(word32 *)((char *)SP1+((t >> 8 ) & 0x3fc))
^ *(word32 *)((char *)SP1+((t >> 16) & 0x3fc))
^ *(word32 *)((char *)SP1+((t >> 24) & 0x0fc));
s = (leftt & 0xfcfcfcfc) ^ keys[2];
t = (((leftt >> 28) | (leftt << 4)) & 0xfcfcfcfc)
^ keys[3];
right ^= *(word32 *)((char *)SP0+( s & 0x3fc))
^ *(word32 *)((char *)SP0+((s >> 8 ) & 0x3fc))
^ *(word32 *)((char *)SP0+((s >> 16) & 0x3fc))
^ *(word32 *)((char *)SP0+((s >> 24) & 0x0fc))
^ *(word32 *)((char *)SP1+( t & 0x3fc))
^ *(word32 *)((char *)SP1+((t >> 8 ) & 0x3fc))
^ *(word32 *)((char *)SP1+((t >> 16) & 0x3fc))
^ *(word32 *)((char *)SP1+((t >> 24) & 0x0fc));
keys += 4;
};
/* Inverse IP */
leftt = ((leftt << 1) | (leftt >> 31));
t = (leftt ^ right) & 0x55555555L;
leftt ^= t;
right ^= t;
right = ((right << 1) | (right >> 31));
t = ((leftt >> 8) ^ right) & 0x00ff00ffL;
right ^= t;
leftt ^= (t << 8);
t = ((leftt >> 2) ^ right) & 0x33333333L;
right ^= t;
leftt ^= (t << 2);
t = ((right >> 16) ^ leftt) & 0x0000ffffL;
leftt ^= t;
right ^= (t << 16);
t = ((right >> 4) ^ leftt) & 0x0f0f0f0fL;
leftt ^= t;
right ^= (t << 4);
outblock[0] = (byte)(right >> 24);
outblock[1] = (byte)(right >> 16);
outblock[2] = (byte)(right >> 8);
outblock[3] = (byte)(right );
outblock[4] = (byte)(leftt >> 24);
outblock[5] = (byte)(leftt >> 16);
outblock[6] = (byte)(leftt >> 8);
outblock[7] = (byte)(leftt );
return;
};
#undef word32
#undef byte
/******************************************************
The Below Code (Package Coder) is Writen In "C++"
*******************************************************/
void CPackage_Encoder::SetKey(const char* password){
unsigned i=0;
SBitBlock key;
key.dword.low=0x476226E8;
key.dword.high=0x87F5F4AD;
while(password[i]){
key.byte[i%8]^=(password[i]+(i>>3)+37);
i++;
};
theDEScoder.SetKey(key);
SetSeed(0x31A68E0D,0x6508CB93);
};
int CPackage_Encoder::Encrypt(unsigned char destination[],const unsigned char source[], unsigned sourcesize)const{
unsigned i,j;
SBitBlock a,b;
theDEScoder.Encrypt(a,seed);
for(i=0;i<8;i++)destination[i]=a.byte[i];
a.dword.low=seed.dword.low;
a.dword.high=seed.dword.high;
for(i=0,j=8;i<sourcesize;i++,j++){
if((i%8)==0){
a.dword.low+=23;
a.dword.high-=71;
theDEScoder.Encrypt(b,a);
};
destination[j]=source[i]^b.byte[i%8];
};
return 0;
};
int CPackage_Encoder::Decrypt(unsigned char destination[],const unsigned char source[], unsigned sourcesize){
unsigned i,j;
SBitBlock a,b;
if(sourcesize<8)return -201; //Too Small Package
for(i=0;i<8;i++)a.byte[i]=source[i];
theDEScoder.Decrypt(seed,a);
a.dword.low=seed.dword.low;
a.dword.high=seed.dword.high;
for(i=0,j=8;j<sourcesize;i++,j++){
if((i%8)==0){
a.dword.low+=23;
a.dword.high-=71;
theDEScoder.Encrypt(b,a);
};
destination[i]=source[j]^b.byte[i%8];
};
return 0;
};
CString CPackage_Encoder::SEncrypt(CString s)
{
int z = s.GetLength();
CString sdet;
unsigned char * src = new unsigned char[z];
for(int i=0;i<z;i++)
src[i] = s[i];
unsigned char * det = new unsigned char[z+8];
Encrypt(det,src, z);
for(i=0;i<z+8;i++)
sdet += det[i];
delete[] det;
delete[] src;
return sdet;
}
CString CPackage_Encoder::SDecrypt(CString s)
{
int z = s.GetLength();
CString sdet;
unsigned char * src = new unsigned char[z+8];
for(int i=0;i<z;i++)
src[i] = s[i];
unsigned char * det = new unsigned char[z];
Decrypt(det,src, z);
for(i=0;i<z-8;i++)
sdet += det[i];
delete[] det;
delete[] src;
return sdet;
}
3 楼
meteor135 [专家分:6060] 发布于 2003-09-21 14:39:00
楼主上面给出的文件不是一个完整的工程,因而无法简单的编译运行,我花了一点时间整理了一下,现重新贴在下面,请大家按要求进行即可,有什么问题请提出。
4 楼
meteor135 [专家分:6060] 发布于 2003-09-21 14:44:00
/*
本项目由3个源文件(分别为下面的三个文件)组成,建立工程时首先需要用vc6.0打开Des.cpp文件,然后直接编译连接,会有两个错误,只需要在VC6.0的Setting中设置Using MFC as static/shared Library即可。
然后添加另外两个文件至工程(这一步可不要)。
再编译连接。
*/
// DES.cpp : Defines the entry point for the console application.
//
#include <iostream.h>
#include "DesCode.h"
int main()
{
CString aa,bb,cc;
aa = "kingwind";
CPackage_Encoder coder1,coder2;
const char k1[256]="dsa3425Hello";
coder1.SetKey(k1);
coder2.SetKey(k1);
cout<<"明文:"<<aa<<endl;
bb = coder1.SEncrypt(aa);
cout<<"密文:"<<bb<<endl;
cc = coder2.SDecrypt(bb);
cout<<"明文:"<<cc<<endl;
return 0;
}
5 楼
meteor135 [专家分:6060] 发布于 2003-09-21 14:45:00
// DesCode.h: interface for the CDesCode class.
//
//////////////////////////////////////////////////////////////////////
#pragma once
#include <afx.h>
typedef union
{
unsigned char byte[8];
struct
{
unsigned long low;
unsigned long high;
}dword;
}SBitBlock;
extern void deskey (unsigned char const *key, int decryptf, unsigned long *outbuf);
extern void desDES (unsigned char const inblock[8], unsigned char outblock[8], unsigned long const *keys);
class CDES_Encoder
{
private:
// Data:16 48-bit k[i], calculated from "key", use low 6-bit in each byte
SBitBlock encrypt_k[16],decrypt_k[16];
public:
inline void SetKey(const SBitBlock& key); //calculate k[i]
inline void Encrypt(SBitBlock& destination, const SBitBlock& source)const;
inline void Decrypt(SBitBlock& destination, const SBitBlock& source)const;
};
// Below defines the package encryption and decryption class
class CPackage_Encoder
{
private:
// Data: a DES coder and package seed
CDES_Encoder theDEScoder;
SBitBlock seed;
public:
void SetKey(const char* password);
inline void SetSeed(unsigned long lo,unsigned long hi);
inline void GetSeed(unsigned long& lo,unsigned long& hi) const;
int Encrypt(unsigned char destination[],const unsigned char source[], unsigned sourcesize)const;
int Decrypt(unsigned char destination[],const unsigned char source[], unsigned sourcesize);
CString SEncrypt(CString);
CString SDecrypt(CString);
};
inline void CDES_Encoder::SetKey(const SBitBlock& key)
{
deskey((unsigned char const*)(&key),0,(unsigned long*)encrypt_k);
deskey((unsigned char const*)(&key),1,(unsigned long*)decrypt_k);
}
inline void CDES_Encoder::Encrypt(SBitBlock& destination, const SBitBlock& source)const
{
desDES((unsigned char const*)(&source),(unsigned char*)(&destination),(unsigned long const*)encrypt_k);
}
inline void CDES_Encoder::Decrypt(SBitBlock& destination, const SBitBlock& source)const
{
desDES((unsigned char const*)(&source),(unsigned char*)(&destination),(unsigned long const*)decrypt_k);
}
inline void CPackage_Encoder::SetSeed(unsigned long lo,unsigned long hi)
{
seed.dword.low=lo;
seed.dword.high=hi;
}
inline void CPackage_Encoder::GetSeed(unsigned long& lo,unsigned long& hi)const
{
lo=seed.dword.low;
hi=seed.dword.high;
}
6 楼
meteor135 [专家分:6060] 发布于 2003-09-21 14:47:00
// DesCode.cpp: implementation of the CDesCode class.
//
//////////////////////////////////////////////////////////////////////
#include "DesCode.h"
#define word32 unsigned long
#define byte unsigned char
extern void deskey (unsigned char const *key, int decryptf, unsigned long *outbuf);
extern void desDES (unsigned char const inblock[8], unsigned char outblock[8], unsigned long const *keys);
/* The size of a scheduled DES key */
#define DES_KEYWORDS 32
#define DES_KEYBYTES (sizeof(word32)*DES_KEYWORDS)
static word32 const bigbyte[24] =
{
0x800000L, 0x400000L, 0x200000L, 0x100000L,
0x80000L, 0x40000L, 0x20000L, 0x10000L,
0x8000L, 0x4000L, 0x2000L, 0x1000L,
0x800L, 0x400L, 0x200L, 0x100L,
0x80L, 0x40L, 0x20L, 0x10L,
0x8L, 0x4L, 0x2L, 0x1L
};
/* Use the key schedule specified in the Standard (ANSI X3.92-1981). */
static byte const pc1[56] =
{
56, 48, 40, 32, 24, 16, 8,
0, 57, 49, 41, 33, 25, 17,
9, 1, 58, 50, 42, 34, 26,
18, 10, 2, 59, 51, 43, 35,
62, 54, 46, 38, 30, 22, 14,
6, 61, 53, 45, 37, 29, 21,
13, 5, 60, 52, 44, 36, 28,
20, 12, 4, 27, 19, 11, 3
};
static byte const totrot[16] =
{
1, 2, 4, 6, 8, 10, 12, 14,
15, 17, 19, 21, 23, 25, 27, 28
};
static byte const pc2[48] =
{
13, 16, 10, 23, 0, 4,
2, 27, 14, 5, 20, 9,
22, 18, 11, 3, 25, 7,
15, 6, 26, 19, 12, 1,
40, 51, 30, 36, 46, 54,
29, 39, 50, 44, 32, 47,
43, 48, 38, 55, 33, 52,
45, 41, 49, 35, 28, 31
};
/*
* This is a less-that-brilliant key scheduling routine.
* It could stand optimization some time.
*
* cookey "cooks" the key into the desired form, from the basic one that
* has the keys for S-boxes 1 through 8 in adjacent words of the
* "raw" array. I.e. the bits start out like this:
* xxxxxxxx111111222222333333444444
* xxxxxxxx555555666666777777888888
* We actually want the keys to look like this:
* 111111xx333333xx555555xx777777xx
* 222222xx444444xx666666xx888888xx
* Where the "xx" patterns are set to 01020300 for use by the s-box
* lookup code in the main encrypt loop.
*/
static void cookey (word32 *raw, word32 *cooked)
{
for (int i = 0; i < 16; i++, raw += 2, cooked += 2)
{
cooked[0] = (raw[0] & 0x00fc0000L) << 8;
cooked[0] |= (raw[0] & 0x00000fc0L) << 12;
cooked[0] |= (raw[1] & 0x00fc0000L) >> 8;
cooked[0] |= (raw[1] & 0x00000fc0L) >> 4;
cooked[0] |= 0x01020300;
cooked[1] = (raw[0] & 0x0003f000L) << 14;
cooked[1] |= (raw[0] & 0x0000003fL) << 18;
cooked[1] |= (raw[1] & 0x0003f000L) >> 2;
cooked[1] |= (raw[1] & 0x0000003fL) << 2;
cooked[1] |= 0x01020300;
}
}
void deskey (byte const *key, int decryptf, word32 *outbuf)
{
int i, j, l, m, n;
byte pc1m[56], pcr[56];
word32 kn[32];
for (j = 0; j < 56; j++)
{
l = pc1[j];
m = l & 07;
pc1m[j] = ( key[l >> 3] >> (~l & 7) ) & 1;
}
for (i = 0; i < 16; i++ )
{
m = (decryptf ? 15-i : i) << 1;
n = m + 1;
kn[m] = kn[n] = 0L;
for (j = 0; j < 28; j++)
{
l = j + totrot[i];
if (l >= 28)
l -= 28;
pcr[j] = pc1m[l];
}
for (j = 28; j < 56; j++)
{
l = j + totrot[i];
if (l >= 56)
l -= 28;
pcr[j] = pc1m[l];
}
for (j = 0; j < 24; j++)
{
if (pcr[pc2[j]])
kn[m] |= bigbyte[j];
if (pcr[pc2[j+24]])
kn[n] |= bigbyte[j];
}
}
cookey(kn, outbuf);
}
/* S-boxes 1, 3, 5, 7, plus P permutation, rotated */
static word32 const SP0[512] =
{
0x00404100, 0x00000000, 0x00004000, 0x00404101,
0x00404001, 0x00004101, 0x00000001, 0x00004000,
0x00000100, 0x00404100, 0x00404101, 0x00000100,
0x00400101, 0x00404001, 0x00400000, 0x00000001,
0x00000101, 0x00400100, 0x00400100, 0x00004100,
0x00004100, 0x00404000, 0x00404000, 0x00400101,
0x00004001, 0x00400001, 0x00400001, 0x00004001,
0x00000000, 0x00000101, 0x00004101, 0x00400000,
0x00004000, 0x00404101, 0x00000001, 0x00404000,
0x00404100, 0x00400000, 0x00400000, 0x00000100,
0x00404001, 0x00004000, 0x00004100, 0x00400001,
0x00000100, 0x00000001, 0x00400101, 0x00004101,
0x00404101, 0x00004001, 0x00404000, 0x00400101,
0x00400001, 0x00000101, 0x00004101, 0x00404100,
0x00000101, 0x00400100, 0x00400100, 0x00000000,
0x00004001, 0x00004100, 0x00000000, 0x00404001,
0x00000082, 0x02008080, 0x00000000, 0x02008002,
0x02000080, 0x00000000, 0x00008082, 0x02000080,
0x00008002, 0x02000002, 0x02000002, 0x00008000,
0x02008082, 0x00008002, 0x02008000, 0x00000082,
0x02000000, 0x00000002, 0x02008080, 0x00000080,
0x00008080, 0x02008000, 0x02008002, 0x00008082,
0x02000082, 0x00008080, 0x00008000, 0x02000082,
0x00000002, 0x02008082, 0x00000080, 0x02000000,
0x02008080, 0x02000000, 0x00008002, 0x00000082,
0x00008000, 0x02008080, 0x02000080, 0x00000000,
0x00000080, 0x00008002, 0x02008082, 0x02000080,
0x02000002, 0x00000080, 0x00000000, 0x02008002,
0x02000082, 0x00008000, 0x02000000, 0x02008082,
0x00000002, 0x00008082, 0x00008080, 0x02000002,
0x02008000, 0x02000082, 0x00000082, 0x02008000,
0x00008082, 0x00000002, 0x02008002, 0x00008080,
0x00000040, 0x00820040, 0x00820000, 0x10800040,
0x00020000, 0x00000040, 0x10000000, 0x00820000,
0x10020040, 0x00020000, 0x00800040, 0x10020040,
0x10800040, 0x10820000, 0x00020040, 0x10000000,
0x00800000, 0x10020000, 0x10020000, 0x00000000,
0x10000040, 0x10820040, 0x10820040, 0x00800040,
0x10820000, 0x10000040, 0x00000000, 0x10800000,
0x00820040, 0x00800000, 0x10800000, 0x00020040,
0x00020000, 0x10800040, 0x00000040, 0x00800000,
0x10000000, 0x00820000, 0x10800040, 0x10020040,
0x00800040, 0x10000000, 0x10820000, 0x00820040,
0x10020040, 0x00000040, 0x00800000, 0x10820000,
0x10820040, 0x00020040, 0x10800000, 0x10820040,
0x00820000, 0x00000000, 0x10020000, 0x10800000,
0x00020040, 0x00800040, 0x10000040, 0x00020000,
0x00000000, 0x10020000, 0x00820040, 0x10000040,
0x00080000, 0x81080000, 0x81000200, 0x00000000,
0x00000200, 0x81000200, 0x80080200, 0x01080200,
0x81080200, 0x00080000, 0x00000000, 0x81000000,
0x80000000, 0x01000000, 0x81080000, 0x80000200,
0x01000200, 0x80080200, 0x80080000, 0x01000200,
0x81000000, 0x01080000, 0x01080200, 0x80080000,
0x01080000, 0x00000200, 0x80000200, 0x81080200,
0x00080200, 0x80000000, 0x01000000, 0x00080200,
0x01000000, 0x00080200, 0x00080000, 0x81000200,
0x81000200, 0x81080000, 0x81080000, 0x80000000,
0x80080000, 0x01000000, 0x01000200, 0x00080000,
0x01080200, 0x80000200, 0x80080200, 0x01080200,
0x80000200, 0x81000000, 0x81080200, 0x01080000,
0x00080200, 0x00000000, 0x80000000, 0x81080200,
0x00000000, 0x80080200, 0x01080000, 0x00000200,
0x81000000, 0x01000200, 0x00000200, 0x80080000
};
/* S-boxes 2, 4, 6, 8, plus P permutation, rotated */
static word32 const SP1[512] =
{
0x20042008, 0x20002000, 0x00002000, 0x00042008,
0x00040000, 0x00000008, 0x20040008, 0x20002008,
0x20000008, 0x20042008, 0x20042000, 0x20000000,
0x20002000, 0x00040000, 0x00000008, 0x20040008,
0x00042000, 0x00040008, 0x20002008, 0x00000000,
0x20000000, 0x00002000, 0x00042008, 0x20040000,
0x00040008, 0x20000008, 0x00000000, 0x00042000,
0x00002008, 0x20042000, 0x20040000, 0x00002008,
0x00000000, 0x00042008, 0x20040008, 0x00040000,
0x20002008, 0x20040000, 0x20042000, 0x00002000,
0x20040000, 0x20002000, 0x00000008, 0x20042008,
0x00042008, 0x00000008, 0x00002000, 0x20000000,
0x00002008, 0x20042000, 0x00040000, 0x20000008,
0x00040008, 0x20002008, 0x20000008, 0x00040008,
0x00042000, 0x00000000, 0x20002000, 0x00002008,
0x20000000, 0x20040008, 0x20042008, 0x00042000,
0x40200800, 0x40000820, 0x40000820, 0x00000020,
0x00200820, 0x40200020, 0x40200000, 0x40000800,
0x00000000, 0x00200800, 0x00200800, 0x40200820,
0x40000020, 0x00000000, 0x00200020, 0x40200000,
0x40000000, 0x00000800, 0x00200000, 0x40200800,
0x00000020, 0x00200000, 0x40000800, 0x00000820,
0x40200020, 0x40000000, 0x00000820, 0x00200020,
0x00000800, 0x00200820, 0x40200820, 0x40000020,
0x00200020, 0x40200000, 0x00200800, 0x40200820,
0x40000020, 0x00000000, 0x00000000, 0x00200800,
0x00000820, 0x00200020, 0x40200020, 0x40000000,
0x40200800, 0x40000820, 0x40000820, 0x00000020,
0x40200820, 0x40000020, 0x40000000, 0x00000800,
0x40200000, 0x40000800, 0x00200820, 0x40200020,
0x40000800, 0x00000820, 0x00200000, 0x40200800,
0x00000020, 0x00200000, 0x00000800, 0x00200820,
0x08000004, 0x08100000, 0x00001000, 0x08101004,
0x08100000, 0x00000004, 0x08101004, 0x00100000,
0x08001000, 0x00101004, 0x00100000, 0x08000004,
0x00100004, 0x08001000, 0x08000000, 0x00001004,
0x00000000, 0x00100004, 0x08001004, 0x00001000,
0x00101000, 0x08001004, 0x00000004, 0x08100004,
0x08100004, 0x00000000, 0x00101004, 0x08101000,
0x00001004, 0x00101000, 0x08101000, 0x08000000,
0x08001000, 0x00000004, 0x08100004, 0x00101000,
0x08101004, 0x00100000, 0x00001004, 0x08000004,
0x00100000, 0x08001000, 0x08000000, 0x00001004,
0x08000004, 0x08101004, 0x00101000, 0x08100000,
0x00101004, 0x08101000, 0x00000000, 0x08100004,
0x00000004, 0x00001000, 0x08100000, 0x00101004,
0x00001000, 0x00100004, 0x08001004, 0x00000000,
0x08101000, 0x08000000, 0x00100004, 0x08001004,
0x04000410, 0x00000400, 0x00010000, 0x04010410,
0x04000000, 0x04000410, 0x00000010, 0x04000000,
0x00010010, 0x04010000, 0x04010410, 0x00010400,
0x04010400, 0x00010410, 0x00000400, 0x00000010,
0x04010000, 0x04000010, 0x04000400, 0x00000410,
0x00010400, 0x00010010, 0x04010010, 0x04010400,
0x00000410, 0x00000000, 0x00000000, 0x04010010,
0x04000010, 0x04000400, 0x00010410, 0x00010000,
0x00010410, 0x00010000, 0x04010400, 0x00000400,
0x00000010, 0x04010010, 0x00000400, 0x00010410,
0x04000400, 0x00000010, 0x04000010, 0x04010000,
0x04010010, 0x04000000, 0x00010000, 0x04000410,
0x00000000, 0x04010410, 0x00010010, 0x04000010,
0x04010000, 0x04000400, 0x04000410, 0x00000000,
0x04010410, 0x00010400, 0x00010400, 0x00000410,
0x00000410, 0x00010010, 0x04000000, 0x04010400
};
/*
* This encryption function is fairly clever in the way it does its
* s-box lookup. The S-boxes are indexed by bytes, rather than
* words, because that's faster on many machines, and shifting
* everything two bits to do the multiply by 4 is trivial.
* Then, the indexing into the various S boxes is done by
* adding the appropriate offset bits into the key array, so the
* addition is done by the XOR with the key rather than having to
* be done explicitly here.
*/
void desDES (byte const inblock[8], byte outblock[8], word32 const *keys)
{
word32 s, t, right, leftt;
int round;
leftt = ((word32)inblock[0] << 24)
| ((word32)inblock[1] << 16)
| ((word32)inblock[2] << 8)
| (word32)inblock[3];
right = ((word32)inblock[4] << 24)
| ((word32)inblock[5] << 16)
| ((word32)inblock[6] << 8)
| (word32)inblock[7];
/* Initial permutation IP */
t = ((leftt >> 4) ^ right) & 0x0f0f0f0fL;
right ^= t;
leftt ^= (t << 4);
t = ((leftt >> 16) ^ right) & 0x0000ffffL;
right ^= t;
leftt ^= (t << 16);
t = ((right >> 2) ^ leftt) & 0x33333333L;
leftt ^= t;
right ^= (t << 2);
t = ((right >> 8) ^ leftt) & 0x00ff00ffL;
leftt ^= t;
right ^= (t << 8);
leftt = ((leftt >> 1) | (leftt << 31));
t = (leftt ^ right) & 0x55555555L;
leftt ^= t;
right ^= t;
right = ((right >> 1) | (right << 31));
for (round = 0; round < 8; round++)
{
s = (right & 0xfcfcfcfc) ^ keys[0];
t = (((right >> 28) | (right << 4)) & 0xfcfcfcfc) ^ keys[1];
leftt ^= *(word32 *)((char *)SP0+( s & 0x3fc))
^ *(word32 *)((char *)SP0+((s >> 8 ) & 0x3fc))
^ *(word32 *)((char *)SP0+((s >> 16) & 0x3fc))
^ *(word32 *)((char *)SP0+((s >> 24) & 0x0fc))
^ *(word32 *)((char *)SP1+( t & 0x3fc))
^ *(word32 *)((char *)SP1+((t >> 8 ) & 0x3fc))
^ *(word32 *)((char *)SP1+((t >> 16) & 0x3fc))
^ *(word32 *)((char *)SP1+((t >> 24) & 0x0fc));
s = (leftt & 0xfcfcfcfc) ^ keys[2];
t = (((leftt >> 28) | (leftt << 4)) & 0xfcfcfcfc) ^ keys[3];
right ^= *(word32 *)((char *)SP0+( s & 0x3fc))
^ *(word32 *)((char *)SP0+((s >> 8 ) & 0x3fc))
^ *(word32 *)((char *)SP0+((s >> 16) & 0x3fc))
^ *(word32 *)((char *)SP0+((s >> 24) & 0x0fc))
^ *(word32 *)((char *)SP1+( t & 0x3fc))
^ *(word32 *)((char *)SP1+((t >> 8 ) & 0x3fc))
^ *(word32 *)((char *)SP1+((t >> 16) & 0x3fc))
^ *(word32 *)((char *)SP1+((t >> 24) & 0x0fc));
keys += 4;
}
/* Inverse IP */
leftt = ((leftt << 1) | (leftt >> 31));
t = (leftt ^ right) & 0x55555555L;
leftt ^= t;
right ^= t;
right = ((right << 1) | (right >> 31));
t = ((leftt >> 8) ^ right) & 0x00ff00ffL;
right ^= t;
leftt ^= (t << 8);
t = ((leftt >> 2) ^ right) & 0x33333333L;
right ^= t;
leftt ^= (t << 2);
t = ((right >> 16) ^ leftt) & 0x0000ffffL;
leftt ^= t;
right ^= (t << 16);
t = ((right >> 4) ^ leftt) & 0x0f0f0f0fL;
leftt ^= t;
right ^= (t << 4);
outblock[0] = (byte)(right >> 24);
outblock[1] = (byte)(right >> 16);
outblock[2] = (byte)(right >> 8);
outblock[3] = (byte)(right );
outblock[4] = (byte)(leftt >> 24);
outblock[5] = (byte)(leftt >> 16);
outblock[6] = (byte)(leftt >> 8);
outblock[7] = (byte)(leftt );
}
#undef word32
#undef byte
/******************************************************
The Below Code (Package Coder) is Writen In "C++"
*******************************************************/
void CPackage_Encoder::SetKey(const char* password)
{
unsigned i=0;
SBitBlock key;
key.dword.low=0x476226E8;
key.dword.high=0x87F5F4AD;
while(password[i])
{
key.byte[i%8]^=(password[i]+(i>>3)+37);
i++;
}
theDEScoder.SetKey(key);
SetSeed(0x31A68E0D,0x6508CB93);
}
int CPackage_Encoder::Encrypt(unsigned char destination[], const unsigned char source[], unsigned sourcesize) const
{
unsigned i,j;
SBitBlock a,b;
theDEScoder.Encrypt(a,seed);
for(i=0;i<8;i++)
destination[i]=a.byte[i];
a.dword.low=seed.dword.low;
a.dword.high=seed.dword.high;
for(i=0,j=8;i<sourcesize;i++,j++)
{
if(i%8==0)
{
a.dword.low+=23;
a.dword.high-=71;
theDEScoder.Encrypt(b,a);
}
destination[j]=source[i]^b.byte[i%8];
}
return 0;
}
int CPackage_Encoder::Decrypt(unsigned char destination[],const unsigned char source[], unsigned sourcesize)
{
unsigned i,j;
SBitBlock a,b;
if(sourcesize<8)
return -201; //Too Small Package
for(i=0;i<8;i++)
a.byte[i]=source[i];
theDEScoder.Decrypt(seed,a);
a.dword.low=seed.dword.low;
a.dword.high=seed.dword.high;
for(i=0,j=8;j<sourcesize;i++,j++)
{
if(i%8==0)
{
a.dword.low+=23;
a.dword.high-=71;
theDEScoder.Encrypt(b,a);
}
destination[i]=source[j]^b.byte[i%8];
}
return 0;
}
CString CPackage_Encoder::SEncrypt(CString s)
{
int z = s.GetLength();
CString sdet;
unsigned char * src = new unsigned char[z];
for(int i=0;i<z;i++)
src[i] = s[i];
unsigned char * det = new unsigned char[z+8];
Encrypt(det,src, z);
for(i=0;i<z+8;i++)
sdet += det[i];
delete[] det;
delete[] src;
return sdet;
}
CString CPackage_Encoder::SDecrypt(CString s)
{
int z = s.GetLength();
CString sdet;
unsigned char * src = new unsigned char[z+8];
for(int i=0;i<z;i++)
src[i] = s[i];
unsigned char * det = new unsigned char[z];
Decrypt(det,src, z);
for(i=0;i<z-8;i++)
sdet += det[i];
delete[] det;
delete[] src;
return sdet;
}
7 楼
autuy123 [专家分:0] 发布于 2003-09-21 18:04:00
可以讲一讲,这些程序的作用吗?讲解的细一点?我们可以看懂呀!
8 楼
月之影 [专家分:80] 发布于 2003-09-22 18:44:00
嗯咳...DES的全称好像应该是Data Encrytion Standard吧...
也就是【数据加密标准】......
由此来看DES加密算法大致就是一种按照DES标准制定的一套替换明文的加密算法...
明文一般按照n比特为单位进行加密(n通常等于64),此算法用一个m比特的密钥作为参数...输出为p比特的密文
从数学的角度,我可以把它简化描述成一个线性时不变因果系统...
设明文为x,密文为y,密钥为m,h为特定的标准明文对于m加密输出的密文
则满足 y(m)=x(m)*h(m)的系统可以算是一个DES线性加密系统...
9 楼
lanjingquan [专家分:510] 发布于 2003-09-23 11:00:00
您现在的位置:胡同口 > 电脑与网络 > 编程技术 > C++Builder论坛 http://d23181823.xici.net
Des加密算法介绍
本帖版权归原作者,其它媒体或网站转载请与e龙西祠胡同[http://www.xici.net]或原作者联系,并注明出处。
作者: 寒山玉 发表日期: 2003-01-16 09:39:53 返回《C++Builder论坛》 快速返回
作者:修罗王
DES 全称为Data Encryption Standard即数据加密算法,它是IBM公司研究成功并公开发表的。
DES算法的入口参数有三个:Key、Data、Mode。其中Key为8个字节共64位,是DES算法的工作密钥;Data也为8个字节64位,是要被加密或被解密的数据;Mode为DES的工作方式,有两种:加密或解密。
DES算法是这样工作的:如Mode为加密,则用Key 去把数据Data进行加密,生成Data的密码形式(64位)作为DES的输出结果;如Mode为解密,则用Key去把密码形式的数据Data解密,还原为Data的明码形式(64位)作为DES的输出结果。在通信网络的两端,双方约定一致的Key,在通信的源点用Key对核心数据进行DES加密,然后以密码形式在公共通信网(如电话网)中传输到通信网络的终点,数据到达目的地后,用同样的Key对密码数据进行解密,便再现了明码形式的核心数据。这样,便保证了核心数据(如PIN、MAC等)在公共通信网中传输的安全性和可靠性。
通过定期在通信网络的源端和目的端同时改用新的Key,便能更进一步提高数据的保密性。
DES算法详述
DES算法把64位的明文输入块变为64位的密文输出块,它所使用的密钥也是64位,整个算法的主流程图如下:
其功能是把输入的64位数据块按位重新组合,并把输出分为L0、R0两部分,每部分各长32位,其置换规则见下表:
58,50,12,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,
即将输入的第58位换到第一位,第50位换到第2位,...,依此类推,最后一位是原来的第7位。L0、R0则是换位输出后的两部分,L0是输出的左32位,R0 是右32位,例:设置换前的输入值为D1D2D3......D64,则经过初始置换后的结果为:L0=D58D50...D8;R0=D57D49...D7。
经过26次迭代运算后。得到L16、R16,将此作为输入,进行逆置换,即得到密文输出。逆置换正好是初始置的逆运算,例如,第1位经过初始置换后,处于第40位,而通过逆置换,又将第40位换回到第1位,其逆置换规则如下表所示:
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,
放大换位表
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,
单纯换位表
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,
在f(Ri,Ki)算法描述图中,S1,S2...S8为选择函数,其功能是把6bit数据变为4bit数据。下面给出选择函数Si(i=1,2......8)的功能表:
选择函数Si
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,
在此以S1为例说明其功能,我们可以看到:在S1中,共有4行数据,命名为0,1、2、3行;每行有16列,命名为0、1、2、3,......,14、15列。
现设输入为: D=D1D2D3D4D5D6
令:列=D2D3D4D5
行=D1D6
然后在S1表中查得对应的数,以4位二进制表示,此即为选择函数S1的输出。下面给出子密钥Ki(48bit)的生成算法
从子密钥Ki的生成算法描述图中我们可以看到:初始Key值为64位,但DES算法规定,其中第8、16、......64位是奇偶校验位,不参与DES运算。故Key 实际可用位数便只有56位。即:经过缩小选择换位表1的变换后,Key 的位数由64 位变成了56位,此56位分为C0、D0两部分,各28位,然后分别进行第1次循环左移,得到C1、D1,将C1(28位)、D1(28位)合并得到56位,再经过缩小选择换位2,从而便得到了密钥K0(48位)。依此类推,便可得到K1、K2、......、K15,不过需要注意的是,16次循环左移对应的左移位数要依据下述规则进行:
循环左移位数
1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1
以上介绍了DES算法的加密过程。DES算法的解密过程是一样的,区别仅仅在于第一次迭代时用子密钥K15,第二次K14、......,最后一次用K0,算法本身并没有任何变化。
打架第一 编程第二 游戏第三 看碟第四
这里没有任何连接
-------------------------------------------------------------
自人类有屎以来我就是一个粪发图强的有痔青年。我学习了四库全
输,站在一个坚腚立场上,认真学习一代萎人的风姿,坚持我行我竖,终
于成为研究僧。作为一个人贱人爱的单身跪族,有时候也会寂寞男耐的。
我向苍天呐喊,我要发炎:老子是妓者,老子靠搞费生活。终于创造了
我伪人的一生光辉的一生……
剩蛋节到了,祝贺大家剩蛋快乐。
萧湘夜雨江中雪,它山之石寒山玉
--------------------------------------------------------------------------------
文章主题:无主题
返回《C++Builder论坛》 快速返回
匆匆过客不能发表言论,请登录或注册新用户名
社区首页 | 胡同简史 | 西祠站规 | 使用指南 | 网络法规 | 隐私保护 | 广告服务 | 用户注册
广告垂询:025-4511487咨询信箱: webmaster@xici.net
站务热线: 025-4511787-205、010-65886448-550
版权所有: eLong.com 京ICP证010011号
10 楼
zhxingxing [专家分:0] 发布于 2003-10-29 22:01:00
看到了!多谢几位版主和朋友热心相助!
我来回复