des加密算法(cc++)

des加密算法(cc++),第1张

desh文件: 

#ifndef CRYPTOPP_DES_H 

#define CRYPTOPP_DES_H 

#include "cryptlibh" 

#include "misch" 

NAMESPACE_BEGIN(CryptoPP) 

class DES : public BlockTransformation 

public: 

DES(const byte userKey, CipherDir); 

void ProcessBlock(const byte inBlock, byte  outBlock) const; 

void ProcessBlock(byte  inoutBlock) const 

{DES::ProcessBlock(inoutBlock, inoutBlock);} 

enum {KEYLENGTH=8, BLOCKSIZE=8}; 

unsigned int BlockSize() const {return BLOCKSIZE;} 

protected: 

static const word32 Spbox[8][64]; 

SecBlock<word32> k; 

}; 

class DESEncryption : public DES 

public: 

DESEncryption(const byte  userKey) 

: DES (userKey, ENCRYPTION) {} 

}; 

class DESDecryption : public DES 

public: 

DESDecryption(const byte  userKey) 

: DES (userKey, DECRYPTION) {} 

}; 

class DES_EDE_Encryption : public BlockTransformation 

public: 

DES_EDE_Encryption(const byte  userKey) 

: e(userKey, ENCRYPTION), d(userKey + DES::KEYLENGTH, DECRYPTION) {} 

void ProcessBlock(const byte inBlock, byte  outBlock) const; 

void ProcessBlock(byte  inoutBlock) const; 

enum {KEYLENGTH=16, BLOCKSIZE=8}; 

unsigned int BlockSize() const {return BLOCKSIZE;} 

private: 

DES e, d; 

}; 

class DES_EDE_Decryption : public BlockTransformation 

public: 

DES_EDE_Decryption(const byte  userKey) 

: d(userKey, DECRYPTION), e(userKey + DES::KEYLENGTH, ENCRYPTION) {} 

void ProcessBlock(const byte inBlock, byte  outBlock) const; 

void ProcessBlock(byte  inoutBlock) const; 

enum {KEYLENGTH=16, BLOCKSIZE=8}; 

unsigned int BlockSize() const {return BLOCKSIZE;} 

private: 

DES d, e; 

}; 

class TripleDES_Encryption : public BlockTransformation 

public: 

TripleDES_Encryption(const byte  userKey) 

: e1(userKey, ENCRYPTION), d(userKey + DES::KEYLENGTH, DECRYPTION), 

e2(userKey + 2DES::KEYLENGTH, ENCRYPTION) {} 

void ProcessBlock(const byte inBlock, byte  outBlock) const; 

void ProcessBlock(byte  inoutBlock) const; 

enum {KEYLENGTH=24, BLOCKSIZE=8}; 

unsigned int BlockSize() const {return BLOCKSIZE;} 

private: 

DES e1, d, e2; 

}; 

class TripleDES_Decryption : public BlockTransformation 

public: 

TripleDES_Decryption(const byte  userKey) 

: d1(userKey + 2DES::KEYLENGTH, DECRYPTION), e(userKey + DES::KEYLENGTH, ENCRYPTION), 

d2(userKey, DECRYPTION) {} 

void ProcessBlock(const byte inBlock, byte  outBlock) const; 

void ProcessBlock(byte  inoutBlock) const; 

enum {KEYLENGTH=24, BLOCKSIZE=8}; 

unsigned int BlockSize() const {return BLOCKSIZE;} 

private: 

DES d1, e, d2; 

}; 

NAMESPACE_END 

#endif 

descpp文件: 

// descpp - modified by Wei Dai from: 

 This is a major rewrite of my old public domain DES code written 

 circa 1987, which in turn borrowed heavily from Jim Gillogly's 1977 

 public domain code I pretty much kept my key scheduling code, but 

 the actual encrypt/decrypt routines are taken from from Richard 

 Outerbridge's DES code as printed in Schneier's "Applied Cryptography" 

 

 This code is in the public domain I would appreciate bug reports and 

 enhancements 

 

 Phil Karn KA9Q, karn@unixka9qamprorg, August 1994 

#include "pchh" 

#include "misch" 

#include "desh" 

NAMESPACE_BEGIN(CryptoPP) 

/ Tables defined in the Data Encryption Standard documents 

 Three of these tables, the initial permutation, the final 

 permutation and the expansion operator, are regular enough that 

 for speed, we hard-code them They're here for reference only 

 Also, the S and P boxes are used by a separate program, genspc, 

 to build the combined SP box, Spbox[] They're also here just 

 for reference 

#ifdef notdef 

/ initial permutation IP / 

static byte ip[] = { 

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 / 

static byte fp[] = { 

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 byte ei[] = { 

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 

}; 

/ The (in)famous S-boxes / 

static byte sbox[8][64] = { 

/ 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 

}; 

/ 32-bit permutation function P used on the output of the S-boxes / 

static byte p32i[] = { 

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 

}; 

#endif 

/ permuted choice table (key) / 

static const byte pc1[] = { 

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 

}; 

/ number left rotations of pc1 / 

static const byte totrot[] = { 

1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28 

}; 

/ permuted choice key (table) / 

static const byte pc2[] = { 

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 

}; 

/ End of DES-defined tables / 

/ bit 0 is left-most in byte / 

static const int bytebit[] = { 

0200,0100,040,020,010,04,02,01 

}; 

/ Set key (initialize key schedule array) / 

DES::DES(const byte key, CipherDir dir) 

: k(32) 

SecByteBlock buffer(56+56+8); 

byte const pc1m=buffer; / place to modify pc1 into / 

byte const pcr=pc1m+56; / place to rotate pc1 into / 

byte const ks=pcr+56; 

register int i,j,l; 

int m; 

for (j=0; j<56; j++) { / convert pc1 to bits of key / 

l=pc1[j]-1; / integer bit location / 

m = l & 07; / find bit / 

pc1m[j]=(key[l>>3] & / find which key byte l is in / 

bytebit[m]) / and which bit of that byte / 

 1 : 0; / and store 1-bit result / 

for (i=0; i<16; i++) { / key chunk for each iteration / 

memset(ks,0,8); / Clear key schedule / 

for (j=0; j<56; j++) / rotate pc1 the right amount / 

pcr[j] = pc1m[(l=j+totrot[i])<(j<28 28 : 56)  l: l-28]; 

/ rotate left and right halves independently / 

for (j=0; j<48; j++){ / select bits individually / 

/ check bit that goes to ks[j] / 

if (pcr[pc2[j]-1]){ 

/ mask it in if it's there / 

l= j % 6; 

ks[j/6] |= bytebit[l] >> 2; 

/ Now convert to odd/even interleaved form for use in F / 

k[2i] = ((word32)ks[0] << 24) 

| ((word32)ks[2] << 16) 

| ((word32)ks[4] << 8) 

| ((word32)ks[6]); 

k[2i+1] = ((word32)ks[1] << 24) 

| ((word32)ks[3] << 16) 

| ((word32)ks[5] << 8) 

| ((word32)ks[7]); 

if (dir==DECRYPTION) // reverse key schedule order 

for (i=0; i<16; i+=2) 

std::swap(k[i], k[32-2-i]); 

std::swap(k[i+1], k[32-1-i]); 

/ End of C code common to both versions / 

/ C code only in portable version / 

// Richard Outerbridge's initial permutation algorithm 

inline void IPERM(word32 &left, word32 &right) 

word32 work; 

work = ((left >> 4) ^ right) & 0x0f0f0f0f; 

right ^= work; 

left ^= work << 4; 

work = ((left >> 16) ^ right) & 0xffff; 

right ^= work; 

left ^= work << 16; 

work = ((right >> 2) ^ left) & 0x33333333; 

left ^= work; 

right ^= (work << 2); 

work = ((right >> 8) ^ left) & 0xff00ff; 

left ^= work; 

right ^= (work << 8); 

right = rotl(right, 1); 

work = (left ^ right) & 0xaaaaaaaa; 

left ^= work; 

right ^= work; 

left = rotl(left, 1); 

inline void FPERM(word32 &left, word32 &right) 

word32 work; 

right = rotr(right, 1); 

work = (left ^ right) & 0xaaaaaaaa; 

left ^= work; 

right ^= work; 

left = rotr(left, 1); 

work = ((left >> 8) ^ right) & 0xff00ff; 

right ^= work; 

left ^= work << 8; 

work = ((left >> 2) ^ right) & 0x33333333; 

right ^= work; 

left ^= work << 2; 

work = ((right >> 16) ^ left) & 0xffff; 

left ^= work; 

right ^= work << 16; 

work = ((right >> 4) ^ left) & 0x0f0f0f0f; 

left ^= work; 

right ^= work << 4; 

// Wei Dai's modification to Richard Outerbridge's initial permutation 

// algorithm, this one is faster if you have access to rotate instructions 

// (like in MSVC) 

inline void IPERM(word32 &left, word32 &right) 

word32 work; 

right = rotl(right, 4U); 

work = (left ^ right) & 0xf0f0f0f0; 

left ^= work; 

right = rotr(right^work, 20U); 

work = (left ^ right) & 0xffff0000; 

left ^= work; 

right = rotr(right^work, 18U); 

work = (left ^ right) & 0x33333333; 

left ^= work; 

right = rotr(right^work, 6U); 

work = (left ^ right) & 0x00ff00ff; 

left ^= work; 

right = rotl(right^work, 9U); 

work = (left ^ right) & 0xaaaaaaaa; 

left = rotl(left^work, 1U); 

right ^= work; 

inline void FPERM(word32 &left, word32 &right) 

word32 work; 

right = rotr(right, 1U); 

work = (left ^ right) & 0xaaaaaaaa; 

right ^= work; 

left = rotr(left^work, 9U); 

work = (left ^ right) & 0x00ff00ff; 

right ^= work; 

left = rotl(left^work, 6U); 

work = (left ^ right) & 0x33333333; 

right ^= work; 

left = rotl(left^work, 18U); 

work = (left ^ right) & 0xffff0000; 

right ^= work; 

left = rotl(left^work, 20U); 

work = (left ^ right) & 0xf0f0f0f0; 

right ^= work; 

left = rotr(left^work, 4U); 

// Encrypt or decrypt a block of data in ECB mode 

void DES::ProcessBlock(const byte inBlock, byte  outBlock) const 

word32 l,r,work; 

#ifdef IS_LITTLE_ENDIAN 

l = byteReverse((word32 )inBlock); 

r = byteReverse((word32 )(inBlock+4)); 

#else 

l = (word32 )inBlock; 

r = (word32 )(inBlock+4); 

#endif 

IPERM(l,r); 

const word32 kptr=k; 

for (unsigned i=0; i<8; i++) 

work = rotr(r, 4U) ^ kptr[4i+0]; 

l ^= Spbox[6][(work) & 0x3f] 

^ Spbox[4][(work >> 8) & 0x3f] 

^ Spbox[2][(work >> 16) & 0x3f] 

^ Spbox[0][(work >> 24) & 0x3f]; 

work = r ^ kptr[4i+1]; 

l ^= Spbox[7][(work) & 0x3f] 

^ Spbox[5][(work >> 8) & 0x3f] 

^ Spbox[3][(work >> 16) & 0x3f] 

^ Spbox[1][(work >> 24) & 0x3f]; 

work = rotr(l, 4U) ^ kptr[4i+2]; 

r ^= Spbox[6][(work) & 0x3f] 

^ Spbox[4][(work >> 8) & 0x3f] 

^ Spbox[2][(work >> 16) & 0x3f] 

^ Spbox[0][(work >> 24) & 0x3f]; 

work = l ^ kptr[4i+3]; 

r ^= Spbox[7][(work) & 0x3f] 

^ Spbox[5][(work >> 8) & 0x3f] 

^ Spbox[3][(work >> 16) & 0x3f] 

^ Spbox[1][(work >> 24) & 0x3f]; 

FPERM(l,r); 

#ifdef IS_LITTLE_ENDIAN 

(word32 )outBlock = byteReverse(r); 

(word32 )(outBlock+4) = byteReverse(l); 

#else 

(word32 )outBlock = r; 

(word32 )(outBlock+4) = l; 

#endif 

void DES_EDE_Encryption::ProcessBlock(byte inoutBlock) const 

eProcessBlock(inoutBlock); 

dProcessBlock(inoutBlock); 

eProcessBlock(inoutBlock); 

void DES_EDE_Encryption::ProcessBlock(const byte inBlock, byte outBlock) const 

eProcessBlock(inBlock, outBlock); 

dProcessBlock(outBlock); 

eProcessBlock(outBlock); 

void DES_EDE_Decryption::ProcessBlock(byte inoutBlock) const 

dProcessBlock(inoutBlock); 

eProcessBlock(inoutBlock); 

dProcessBlock(inoutBlock); 

void DES_EDE_Decryption::ProcessBlock(const byte inBlock, byte outBlock) const 

dProcessBlock(inBlock, outBlock); 

eProcessBlock(outBlock); 

dProcessBlock(outBlock); 

void TripleDES_Encryption::ProcessBlock(byte inoutBlock) const 

e1ProcessBlock(inoutBlock); 

dProcessBlock(inoutBlock); 

e2ProcessBlock(inoutBlock); 

void TripleDES_Encryption::ProcessBlock(const byte inBlock, byte outBlock) const 

e1ProcessBlock(inBlock, outBlock); 

dProcessBlock(outBlock); 

e2ProcessBlock(outBlock); 

void TripleDES_Decryption::ProcessBlock(byte inoutBlock) const 

d1ProcessBlock(inoutBlock); 

eProcessBlock(inoutBlock); 

d2ProcessBlock(inoutBlock); 

void TripleDES_Decryption::ProcessBlock(const byte inBlock, byte outBlock) const 

d1ProcessBlock(inBlock, outBlock); 

eProcessBlock(outBlock); 

d2ProcessBlock(outBlock); 

NAMESPACE_END

程序运行如下:

DES(Data Encryption Standard)是一种常见的分组加密算法,由IBM公司在1971年提出。它是一种对称加密算法,也就是说它使用同一个密钥来加密和解密数据。

DES使用一个56位的初始密钥,但是这里提供的是一个64位的值,这是因为在硬件实现中每8位可以用于奇偶校验。可以通过设定8位字符串,由 crypto/des 库的 desNewCipher(key) 函数生成密钥

DES分组的大小是64位,如果加密的数据长度不是64位的倍数,可以按照某种具体的规则来填充位。常用的填充算法有 pkcs5 , zero 等

没有软件就比较麻烦了,这个软件上实现比较容易。

算法主要包括:

16个子密钥产生器

初始置换IP

16轮迭代的乘积变换 — 关键

逆初始置换IP-1

•PC-1 (Permuted Choice):

–负责取出由用户提供的56bits密钥(即去除第8,16,24,32,40,48,56,64位),并置换

–将56bits分成左右两半,并分别存到C0和D0中

•计算第i个子密钥ki (i=1,2,3,, 16)

–将Ci-1和Di-1分别循环左移指定位数,对应的结果分别存到Ci和Di中

–将Ci和Di整合后,进行压缩置换(PC-2):

•抛弃8位,得到48位的子密钥;并置换

初始置换IP和逆初始置换IP-1

•初始置换IP

–将64 bit明文的位置进行置换,得到一个乱序的64 bit明文组

–而后成左右两段,每段为32 bit,以L0和R0表示

•逆初始置换IP-1。将16轮迭代后给出的64 bit组进行置换,得到输出的密文组。输出为阵中元素按行读得的结果。

•IP和IP-1在密码意义上作用不大,它们的作用在于打乱原来输入x的ASCII码字划分的关系,并将原来明文的校验位x8, x16,L, x64变成为IP输出的一个字节。

•乘积变换是DES算法的核心部分。

•三个关键函数:

–扩展函数E

–选择压缩运算S(S盒)

–置换运算P(P盒)

/// <summary>

/// 加密原函数

/// </summary>

/// <param name="str_in_data">加密原串</param>

/// <param name="str_DES_KEY">密钥</param>

/// <returns>加密串</returns>

public static string Encrypt_DES16(string str_in_data, string str_DES_KEY)

{

try

{

byte[] shuju = new byte[8];

byte[] keys = new byte[8];

for (int i = 0; i < 8; i++)

{

shuju[i] = ConvertToByte(str_in_dataSubstring(i 2, 2), 16);

keys[i] = ConvertToByte(str_DES_KEYSubstring(i 2, 2), 16);

}

DES desEncrypt = new DESCryptoServiceProvider();

desEncryptMode = CipherModeECB;

//desEncryptKey = ASCIIEncodingASCIIGetBytes(str_DES_KEY);

desEncryptKey = keys;

byte[] Buffer;

Buffer = shuju;//ASCIIEncodingASCIIGetBytes(str_in_data);

ICryptoTransform transForm = desEncryptCreateEncryptor();

byte[] R;

R = transFormTransformFinalBlock(Buffer, 0, BufferLength);

string return_str = "";

foreach (byte b in R)

{

return_str += bToString("X2");

}

return_str = return_strSubstring(0, 16);

return return_str;

}

catch (Exception e)

{

throw e;

}

}

随机密钥加密算法:RC4

位密码算法:DES 三重DES(Triple-DES)仍然是很安全的,但是也只是在别无他法的情况下的一个较好的选择。显然高级加密标准(AES)是一个更好的加密算法,NIST用AES代替Triple-DES作为他们的标准(下面有更详细的讨论)。其他较好的算法包括另外两个AES的变种算法Twofish和Serpent-也称为CAST-128,它是效率和安全的完美结合。这几个算法不仅比DES更安全,而且也比DES的速度更快。为什么要使用一些又慢又不安全的算法呢?SHA1是一个哈希函数,而不是一个加密函数。作为一个哈希函数,SHA1还是相当优秀的,但是还需要几年的发展才能用作加密算法。如果你正在设计一个新系统,那么谨记你可能会在若干年后用SHA1代替目前的算法。我再重复一遍:只是可能。呵呵,希望能帮到你!谢谢望采纳哦!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://www.54852.com/langs/13493562.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2025-09-01
下一篇2025-09-01

发表评论

登录后才能评论

评论列表(0条)

    保存