DES加密算法代码(des加密算法的加密过程)

2023-02-28 13:56:00 密码用途 思思

des算法源代码

des.h文件:

#ifndef CRYPTOPP_DES_H

#define CRYPTOPP_DES_H

#include "cryptlib.h"

#include "misc.h"

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];

SecBlockword32 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 + 2*DES::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 + 2*DES::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

des.cpp文件:

// des.cpp - 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@unix.ka9q.ampr.org, August 1994.

*/

#include "pch.h"

#include "misc.h"

#include "des.h"

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, gensp.c,

* 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; j56; j++) { /* convert pc1 to bits of key */

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

m = l 07; /* find bit */

pc1m[j]=(key[l3] /* 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; i16; i++) { /* key chunk for each iteration */

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

for (j=0; j56; j++) /* rotate pc1 the right amount */

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

/* rotate left and right halves independently */

for (j=0; j48; 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[2*i] = ((word32)ks[0] 24)

| ((word32)ks[2] 16)

| ((word32)ks[4] 8)

| ((word32)ks[6]);

k[2*i+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; i16; 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; i8; i++)

{

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

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

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

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

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

work = r ^ kptr[4*i+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[4*i+2];

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

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

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

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

work = l ^ kptr[4*i+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

{

e.ProcessBlock(inoutBlock);

d.ProcessBlock(inoutBlock);

e.ProcessBlock(inoutBlock);

}

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

{

e.ProcessBlock(inBlock, outBlock);

d.ProcessBlock(outBlock);

e.ProcessBlock(outBlock);

}

void DES_EDE_Decryption::ProcessBlock(byte *inoutBlock) const

{

d.ProcessBlock(inoutBlock);

e.ProcessBlock(inoutBlock);

d.ProcessBlock(inoutBlock);

}

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

{

d.ProcessBlock(inBlock, outBlock);

e.ProcessBlock(outBlock);

d.ProcessBlock(outBlock);

}

void TripleDES_Encryption::ProcessBlock(byte *inoutBlock) const

{

e1.ProcessBlock(inoutBlock);

d.ProcessBlock(inoutBlock);

e2.ProcessBlock(inoutBlock);

}

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

{

e1.ProcessBlock(inBlock, outBlock);

d.ProcessBlock(outBlock);

e2.ProcessBlock(outBlock);

}

void TripleDES_Decryption::ProcessBlock(byte *inoutBlock) const

{

d1.ProcessBlock(inoutBlock);

e.ProcessBlock(inoutBlock);

d2.ProcessBlock(inoutBlock);

}

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

{

d1.ProcessBlock(inBlock, outBlock);

e.ProcessBlock(outBlock);

d2.ProcessBlock(outBlock);

}

NAMESPACE_END

DES加密算法代码(des加密算法的加密过程) 第1张

des加密算法

des加密算法如下:

一、DES加密算法简介

DES(Data Encryption Standard)是目前最为流行的加密算法之一。DES是对称的,也就是说它使用同一个密钥来加密和解密数据。

DES还是一种分组加密算法,该算法每次处理固定长度的数据段,称之为分组。DES分组的大小是64位,如果加密的数据长度不是64位的倍数,可以按照某种具体的规则来填充位。

从本质上来说,DES的安全性依赖于虚假表象,从密码学的术语来讲就是依赖于“混乱和扩散”的原则。混乱的目的是为隐藏任何明文同密文、或者密钥之间的关系,而扩散的目的是使明文中的有效位和密钥一起组成尽可能多的密文。两者结合到一起就使得安全性变得相对较高。

DES算法具体通过对明文进行一系列的排列和替换操作来将其加密。过程的关键就是从给定的初始密钥中得到16个子密钥的函数。要加密一组明文,每个子密钥按照顺序(1-16)以一系列的位操作施加于数据上,每个子密钥一次,一共重复16次。每一次迭代称之为一轮。要对密文进行解密可以采用同样的步骤,只是子密钥是按照逆向的顺序(16-1)对密文进行处理。

二、DES加密算法加密原理

DES是采用分组加密。使用64位的分组长度和56位的密钥长度,将64位的输入经过一系列变换得到64位的输出。DES算法利用多次组合替代算法和换位算法,通过混淆和扩散的相互作用,把明文编辑成密码强度很高的密文。解密则使用了相同的步骤和相同的密钥。

64位数据为一组进行加密;

初始置换根据一张8*8的置换表,将64位的明文打乱

与56位的密钥经16轮次迭代运算形成的初始密文

最后经过初始逆置换得到分组的最终密文

如何使用JAVA实现对字符串的DES加密和解密

java加密字符串可以使用des加密算法,实例如下:

package test;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.ObjectInputStream;

import java.io.ObjectOutputStream;

import java.security.*;

import javax.crypto.Cipher;

import javax.crypto.KeyGenerator;

import javax.crypto.SecretKey;

/**

* 加密解密

*

* @author shy.qiu

* @since

*/

public class CryptTest {

/**

* 进行MD5加密

*

* @param info

* 要加密的信息

* @return String 加密后的字符串

*/

public String encryptToMD5(String info) {

byte[] digesta = null;

try {

// 得到一个md5的消息摘要

MessageDigest alga = MessageDigest.getInstance("MD5");

// 添加要进行计算摘要的信息

alga.update(info.getBytes());

// 得到该摘要

digesta = alga.digest();

} catch (NoSuchAlgorithmException e) {

e.printStackTrace();

}

// 将摘要转为字符串

String rs = byte2hex(digesta);

return rs;

}

/**

* 进行SHA加密

*

* @param info

* 要加密的信息

* @return String 加密后的字符串

*/

public String encryptToSHA(String info) {

byte[] digesta = null;

try {

// 得到一个SHA-1的消息摘要

MessageDigest alga = MessageDigest.getInstance("SHA-1");

// 添加要进行计算摘要的信息

alga.update(info.getBytes());

// 得到该摘要

digesta = alga.digest();

} catch (NoSuchAlgorithmException e) {

e.printStackTrace();

}

// 将摘要转为字符串

String rs = byte2hex(digesta);

return rs;

}

// //////////////////////////////////////////////////////////////////////////

/**

* 创建密匙

*

* @param algorithm

* 加密算法,可用 DES,DESede,Blowfish

* @return SecretKey 秘密(对称)密钥

*/

public SecretKey createSecretKey(String algorithm) {

// 声明KeyGenerator对象

KeyGenerator keygen;

// 声明 密钥对象

SecretKey deskey = null;

try {

// 返回生成指定算法的秘密密钥的 KeyGenerator 对象

keygen = KeyGenerator.getInstance(algorithm);

// 生成一个密钥

deskey = keygen.generateKey();

} catch (NoSuchAlgorithmException e) {

e.printStackTrace();

}

// 返回密匙

return deskey;

}

/**

* 根据密匙进行DES加密

*

* @param key

* 密匙

* @param info

* 要加密的信息

* @return String 加密后的信息

*/

public String encryptToDES(SecretKey key, String info) {

// 定义 加密算法,可用 DES,DESede,Blowfish

String Algorithm = "DES";

// 加密随机数生成器 (RNG),(可以不写)

SecureRandom sr = new SecureRandom();

// 定义要生成的密文

byte[] cipherByte = null;

try {

// 得到加密/解密器

Cipher c1 = Cipher.getInstance(Algorithm);

// 用指定的密钥和模式初始化Cipher对象

// 参数:(ENCRYPT_MODE, DECRYPT_MODE, WRAP_MODE,UNWRAP_MODE)

c1.init(Cipher.ENCRYPT_MODE, key, sr);

// 对要加密的内容进行编码处理,

cipherByte = c1.doFinal(info.getBytes());

} catch (Exception e) {

e.printStackTrace();

}

// 返回密文的十六进制形式

return byte2hex(cipherByte);

}

/**

* 根据密匙进行DES解密

*

* @param key

* 密匙

* @param sInfo

* 要解密的密文

* @return String 返回解密后信息

*/

public String decryptByDES(SecretKey key, String sInfo) {

// 定义 加密算法,

String Algorithm = "DES";

// 加密随机数生成器 (RNG)

SecureRandom sr = new SecureRandom();

byte[] cipherByte = null;

try {

// 得到加密/解密器

Cipher c1 = Cipher.getInstance(Algorithm);

// 用指定的密钥和模式初始化Cipher对象

c1.init(Cipher.DECRYPT_MODE, key, sr);

// 对要解密的内容进行编码处理

cipherByte = c1.doFinal(hex2byte(sInfo));

} catch (Exception e) {

e.printStackTrace();

}

// return byte2hex(cipherByte);

return new String(cipherByte);

}

// /////////////////////////////////////////////////////////////////////////////

/**

* 创建密匙组,并将公匙,私匙放入到指定文件中

*

* 默认放入mykeys.bat文件中

*/

public void createPairKey() {

try {

// 根据特定的算法一个密钥对生成器

KeyPairGenerator keygen = KeyPairGenerator.getInstance("DSA");

// 加密随机数生成器 (RNG)

SecureRandom random = new SecureRandom();

// 重新设置此随机对象的种子

random.setSeed(1000);

// 使用给定的随机源(和默认的参数集合)初始化确定密钥大小的密钥对生成器

keygen.initialize(512, random);// keygen.initialize(512);

// 生成密钥组

KeyPair keys = keygen.generateKeyPair();

// 得到公匙

PublicKey pubkey = keys.getPublic();

// 得到私匙

PrivateKey prikey = keys.getPrivate();

// 将公匙私匙写入到文件当中

doObjToFile("mykeys.bat", new Object[] { prikey, pubkey });

} catch (NoSuchAlgorithmException e) {

e.printStackTrace();

}

}

/**

* 利用私匙对信息进行签名 把签名后的信息放入到指定的文件中

*

* @param info

* 要签名的信息

* @param signfile

* 存入的文件

*/

public void signToInfo(String info, String signfile) {

// 从文件当中读取私匙

PrivateKey myprikey = (PrivateKey) getObjFromFile("mykeys.bat", 1);

// 从文件中读取公匙

PublicKey mypubkey = (PublicKey) getObjFromFile("mykeys.bat", 2);

try {

// Signature 对象可用来生成和验证数字签名

Signature signet = Signature.getInstance("DSA");

// 初始化签署签名的私钥

signet.initSign(myprikey);

// 更新要由字节签名或验证的数据

signet.update(info.getBytes());

// 签署或验证所有更新字节的签名,返回签名

byte[] signed = signet.sign();

// 将数字签名,公匙,信息放入文件中

doObjToFile(signfile, new Object[] { signed, mypubkey, info });

} catch (Exception e) {

e.printStackTrace();

}

}

/**

* 读取数字签名文件 根据公匙,签名,信息验证信息的合法性

*

* @return true 验证成功 false 验证失败

*/

public boolean validateSign(String signfile) {

// 读取公匙

PublicKey mypubkey = (PublicKey) getObjFromFile(signfile, 2);

// 读取签名

byte[] signed = (byte[]) getObjFromFile(signfile, 1);

// 读取信息

String info = (String) getObjFromFile(signfile, 3);

try {

// 初始一个Signature对象,并用公钥和签名进行验证

Signature signetcheck = Signature.getInstance("DSA");

// 初始化验证签名的公钥

signetcheck.initVerify(mypubkey);

// 使用指定的 byte 数组更新要签名或验证的数据

signetcheck.update(info.getBytes());

System.out.println(info);

// 验证传入的签名

return signetcheck.verify(signed);

} catch (Exception e) {

e.printStackTrace();

return false;

}

}

/**

* 将二进制转化为16进制字符串

*

* @param b

* 二进制字节数组

* @return String

*/

public String byte2hex(byte[] b) {

String hs = "";

String stmp = "";

for (int n = 0; n b.length; n++) {

stmp = (java.lang.Integer.toHexString(b[n] 0XFF));

if (stmp.length() == 1) {

hs = hs + "0" + stmp;

} else {

hs = hs + stmp;

}

}

return hs.toUpperCase();

}

/**

* 十六进制字符串转化为2进制

*

* @param hex

* @return

*/

public byte[] hex2byte(String hex) {

byte[] ret = new byte[8];

byte[] tmp = hex.getBytes();

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

ret[i] = uniteBytes(tmp[i * 2], tmp[i * 2 + 1]);

}

return ret;

}

/**

* 将两个ASCII字符合成一个字节; 如:"EF"-- 0xEF

*

* @param src0

* byte

* @param src1

* byte

* @return byte

*/

public static byte uniteBytes(byte src0, byte src1) {

byte _b0 = Byte.decode("0x" + new String(new byte[] { src0 }))

.byteValue();

_b0 = (byte) (_b0 4);

byte _b1 = Byte.decode("0x" + new String(new byte[] { src1 }))

.byteValue();

byte ret = (byte) (_b0 ^ _b1);

return ret;

}

/**

* 将指定的对象写入指定的文件

*

* @param file

* 指定写入的文件

* @param objs

* 要写入的对象

*/

public void doObjToFile(String file, Object[] objs) {

ObjectOutputStream oos = null;

try {

FileOutputStream fos = new FileOutputStream(file);

oos = new ObjectOutputStream(fos);

for (int i = 0; i objs.length; i++) {

oos.writeObject(objs[i]);

}

} catch (Exception e) {

e.printStackTrace();

} finally {

try {

oos.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

/**

* 返回在文件中指定位置的对象

*

* @param file

* 指定的文件

* @param i

* 从1开始

* @return

*/

public Object getObjFromFile(String file, int i) {

ObjectInputStream ois = null;

Object obj = null;

try {

FileInputStream fis = new FileInputStream(file);

ois = new ObjectInputStream(fis);

for (int j = 0; j i; j++) {

obj = ois.readObject();

}

} catch (Exception e) {

e.printStackTrace();

} finally {

try {

ois.close();

} catch (IOException e) {

e.printStackTrace();

}

}

return obj;

}

/**

* 测试

*

* @param args

*/

public static void main(String[] args) {

CryptTest jiami = new CryptTest();

// 执行MD5加密"Hello world!"

System.out.println("Hello经过MD5:" + jiami.encryptToMD5("Hello"));

// 生成一个DES算法的密匙

SecretKey key = jiami.createSecretKey("DES");

// 用密匙加密信息"Hello world!"

String str1 = jiami.encryptToDES(key, "Hello");

System.out.println("使用des加密信息Hello为:" + str1);

// 使用这个密匙解密

String str2 = jiami.decryptByDES(key, str1);

System.out.println("解密后为:" + str2);

// 创建公匙和私匙

jiami.createPairKey();

// 对Hello world!使用私匙进行签名

jiami.signToInfo("Hello", "mysign.bat");

// 利用公匙对签名进行验证。

if (jiami.validateSign("mysign.bat")) {

System.out.println("Success!");

} else {

System.out.println("Fail!");

}

}

}

用c语言写des加密算法

#include stdio.h #include string.h #include windows.h #include conio.h #include "Schedle.h" class CShift{ public: DWORDLONG mask[16]; int step[16]; CShift(){ for(int i=0;i16;i++){ step[i]=2; mask[i]=0xc000000; } step[0]=step[1]=step[8]=step[15]=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); //PrintTable(dwlKey_PC_1,7,8); ConvertTableToMask(dwlKey_PC_2,56); ConvertTableToMask(dwlData_IP,64); ConvertTableToMask(dwlData_Expansion,32); ConvertTableToMask(dwlData_FP,64); ConvertTableToMask(dwlData_P,32); Generate_S(); } void PrintBit(DWORDLONG); void EncryptKey(char *); unsigned char* EncryptData(unsigned char *); unsigned char* DescryptData(unsigned char*); private: void ConvertTableToMask(DWORDLONG *,int); void Generate_S(void); void PrintTable(DWORDLONG*,int,int); DWORDLONG ProcessByte(unsigned char*,BOOL); DWORDLONG PermuteTable(DWORDLONG,DWORDLONG*,int); void Generate_K(void); void EncryptKernel(void); DWORDLONG Generate_B(DWORDLONG,DWORDLONG*); /*For verify schedule permutation only*/ DWORDLONG UnPermuteTable(DWORDLONG,DWORDLONG*,int); /**************************************/ 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("\nOriginal Key: %s",key); m_dwlKey=ProcessByte((unsigned char*)key,TRUE); // PrintBit(m_dwlKey); m_dwlKey=PermuteTable(m_dwlKey,dwlKey_PC_1,56); // PrintBit(m_dwlKey); Generate_K(); // printf("\n******************************************\n"); } void CDES::Generate_K(void){ DWORDLONG C[17],D[17],tmp; C[0]=m_dwlKey28; D[0]=m_dwlKey0xfffffff; 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){ unsigned char tmp; DWORDLONG byte=0; int i=0; while(i8){ while(*key){ if(byte!=0) byte=8; tmp=*key; if(shift) tmp=1; byte|=tmp; i++; key++; } if(i8) byte=8; i++; } return byte; } DWORDLONG CDES::PermuteTable(DWORDLONG dwlPara,DWOR 基于des算法的rfid安全系统

DLONG* dwlTable,int nDestLen){ int i=0; DWORDLONG tmp=0,moveBit; while(inDestLen){ moveBit=1; if(dwlTable[i]dwlPara){ moveBit=nDestLen-i-1; tmp|=moveBit; } i++; } return tmp; } DWORDLONG CDES::UnPermuteTable(DWORDLONG dwlPara,DWORDLONG* dwlTable,int nDestLen){ DWORDLONG tmp=0; int i=nDestLen-1; while(dwlPara!=0){ if(dwlPara0x01) tmp|=dwlTable[i]; dwlPara=1; i--; } return tmp; } void CDES::PrintTable(DWORDLONG *dwlPara,int col,int row){ int i,j; for(i=0;irow;i++){ printf("\n"); getch(); for(j=0;jcol;j++) PrintBit(dwlPara[i*col+j]); } } void CDES::PrintBit(DWORDLONG bitstream){ char out[76]; int i=0,j=0,space=0; while(bitstream!=0){ if(bitstream0x01) out[i++]='1'; else out[i++]='0'; j++; if(j%8==0){ out[i++]=' '; space++; } bitstream=bitstream1; } out[i]='\0'; strcpy(out,strrev(out)); printf("%s **:%d\n",out,i-space); } 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){ int i; int j,m,n; m=n=0; j=1; for(i=0;i512;i++){ dwlData_S[j][m][n]=OS[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("\nOriginal Data: %s\n",block); m_dwlData=ProcessByte(block,0); // PrintBit(m_dwlData); m_dwlData=PermuteTable(m_dwlData,dwlData_IP,64); EncryptKernel(); // PrintBit(m_dwlData); DWORDLONG bit6=m_dwlData; for(int i=0;i11;i++){ EncrytedData[7-i]=(unsigned char)(bit60x3f)+46; bit6=6; } EncrytedData[11]='\0'; printf("\nAfter Encrypted: %s",EncrytedData); for(i=0;i8;i++){ EncrytedData[7-i]=(unsigned char)(m_dwlData0xff); 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_dwlData32; R[0]=m_dwlData0xffffffff; for(i=1;i=16;i++){ L[i]=R[i-1]; R[i-1]=PermuteTable(R[i-1],dwlData_Expansion,48); //Expansion R EK=R[i-1]^m_dwl_K[i]; //E Permutation PSB=Generate_B(EK,B); //P Permutation 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]=dataPara32; L[16]=dataPara0xffffffff; for(i=16;i=1;i--){ R[i-1]=L[i]; L[i]=PermuteTable(L[i],dwlData_Expansion,48); //Expansion L EK=L[i]^m_dwl_K[i]; //E Permutation PSB=Generate_B(EK,B); //P Permutation L[i-1]=R[i]^PSB; } L[0]=32; dataPara=L[0]|R[0]; dataPara=PermuteTable(dataPara,dwlData_FP,64); // PrintBit(dataPara); for(i=0;i8;i++){ DescryptedData[7-i]=(unsigned char)(dataPara0xff); dataPara=8; } DescryptedData[8]='\0'; printf("\nAfter Decrypted: %s\n",DescryptedData); return DescryptedData; } DWORDLONG CDES::Generate_B(DWORDLONG EKPara,DWORDLONG *block){ int i,m,n; DWORDLONG tmp=0; for(i=8;i0;i--){ block[i]=EKPara0x3f; 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); return tmp; } void main(void){ CDES des; des.EncryptKey("12345678"); unsigned char *result=des.EncryptData((unsigned char*)"DemoData"); des.DescryptData(result); }[1]

DES加密算法C语言实现

#includeiostream.h

class SubKey{ //定义子密钥为一个类

public:

int key[8][6];

}subkey[16]; //定义子密钥对象数组

class DES{

int encipher_decipher; //判断加密还是解密

int key_in[8][8]; //用户原始输入的64位二进制数

int key_out[8][7]; //除去每行的最后一位校验位

int c0_d0[8][7]; //存储经PC-1转换后的56位数据

int c0[4][7],d0[4][7]; //分别存储c0,d0

int text[8][8]; //64位明文

int text_ip[8][8]; //经IP转换过后的明文

int A[4][8],B[4][8]; //A,B分别存储经IP转换过后明文的两部分,便于交换

int temp[8][6]; //存储经扩展置换后的48位二进制值

int temp1[8][6]; //存储和子密钥异或后的结果

int s_result[8][4]; //存储经S变换后的32位值

int text_p[8][4]; //经P置换后的32位结果

int secret_ip[8][8]; //经逆IP转换后的密文

public:

void Key_Putting();

void PC_1();

int function(int,int); //异或

void SubKey_Production();

void IP_Convert();

void f();

void _IP_Convert();

void Out_secret();

};

void DES::Key_Putting() //得到密钥中对算法有用的56位

{

cout"请输入64位的密钥(8行8列且每行都得有奇数个1):\n";

for(int i=0;i8;i++)

for(int j=0;j8;j++){

cinkey_in[i][j];

if(j!=7) key_out[i][j]=key_in[i][j];

}

}

void DES::PC_1() //PC-1置换函数

{

int pc_1[8][7]={ //PC-1

{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}

};

int i,j;

for(i=0;i8;i++)

for(j=0;j7;j++)

c0_d0[i][j]=key_out[ (pc_1[i][j]-1)/8 ][ (pc_1[i][j]-1)%8 ];

}

int DES::function(int a,int b) //模拟二进制数的异或运算,a和b为整型的0和1,返回值为整型的0或1

{

if(a!=b)return 1;

else return 0;

}

void DES::SubKey_Production() //生成子密钥

{

int move[16][2]={ //循环左移的位数

1 , 1 , 2 , 1 ,

3 , 2 , 4 , 2 ,

5 , 2 , 6 , 2 ,

7 , 2 , 8 , 2 ,

9 , 1, 10 , 2,

11 , 2, 12 , 2,

13 , 2, 14 , 2,

15 , 2, 16 , 1

};

int pc_2[8][6]={ //PC-2

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

};

for(int i=0;i16;i++) //生成子密钥

{

int j,k;

int a[2],b[2];

int bb[28],cc[28];

for(j=0;j4;j++)

for(k=0;k7;k++)

c0[j][k]=c0_d0[j][k];

for(j=4;j8;j++)

for(k=0;k7;k++)

d0[j-4][k]=c0_d0[j][k];

for(j=0;j4;j++)

for(k=0;k7;k++){

bb[7*j+k]=c0[j][k];

cc[7*j+k]=d0[j][k];

}

for(j=0;jmove[i][1];j++){

a[j]=bb[j];

b[j]=cc[j];

}

for(j=0;j28-move[i][1];j++){

bb[j]=bb[j+1];

cc[j]=cc[j+1];

}

for(j=0;jmove[i][1];j++){

bb[27-j]=a[j];

cc[27-j]=b[j];

}

for(j=0;j28;j++){

c0[j/7][j%7]=bb[j];

d0[j/7][j%7]=cc[j];

}

for(j=0;j4;j++) //L123--L128是把c0,d0合并成c0_d0

for(k=0;k7;k++)

c0_d0[j][k]=c0[j][k];

for(j=4;j8;j++)

for(k=0;k7;k++)

c0_d0[j][k]=d0[j-4][k];

for(j=0;j8;j++) //对Ci,Di进行PC-2置换

for(k=0;k6;k++)

subkey[i].key[j][k]=c0_d0[ (pc_2[j][k]-1)/7 ][ (pc_2[j][k]-1)%7 ];

}

}

void DES::IP_Convert()

{

int IP[8][8]={ //初始置换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

};

cout"你好,你要加密还是解密?加密请按1号键(输入1),解密请按2号键,并确定."'\n';

cinencipher_decipher;

char * s;

if(encipher_decipher==1) s="明文";

else s="密文";

cout"请输入64位"s"(二进制):\n";

int i,j;

for(i=0;i8;i++)

for(j=0;j8;j++)

cintext[i][j];

for(i=0;i8;i++) //进行IP变换

for(j=0;j8;j++)

text_ip[i][j]=text[ (IP[i][j]-1)/8 ][ (IP[i][j]-1)%8 ];

}