当前位置:首页 > 代码 > 正文

des加密解密源代码(des加密算法源代码)

admin 发布:2022-12-19 19:31 112


本篇文章给大家谈谈des加密解密源代码,以及des加密算法源代码对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。

本文目录一览:

如何利用DES加密的算法保护Java源代码

Java语言是一种非常适用于网络编程的语言,它的基本结构与C++极为相似,但抛弃了C/C++中指针等内容,同时它吸收了Smalltalk、C++面向对象的编程思想。它具有简单性、鲁棒性、可移植性、动态性等特点。这些特点使得Java成为跨平台应用开发的一种规范,在世界范围内广泛流传。 加密Java源码的原因 Java源代码经过编译以后在JVM中执行。由于JVM界面是完全透明的,Java类文件能够很容易通过反编译器重新转换成源代码。因此,所有的算法、类文件等都可以以源代码的形式被公开,使得软件不能受到保护,为了保护产权,一般可以有以下几种方法: (1)"模糊"类文件,加大反编译器反编译源代码文件的难度。然而,可以修改反编译器,使之能够处理这些模糊类文件。所以仅仅依赖"模糊类文件"来保证代码的安全是不够的。 (2)流行的加密工具对源文件进行加密,比如PGP(Pretty Good Privacy)或GPG(GNU Privacy Guard)。这时,最终用户在运行应用之前必须先进行解密。但解密之后,最终用户就有了一份不加密的类文件,这和事先不进行加密没有什么差别。 (3)加密类文件,在运行中JVM用定制的类装载器(Class Loader)解密类文件。Java运行时装入字节码的机制隐含地意味着可以对字节码进行修改。JVM每次装入类文件时都需要一个称为ClassLoader的对象,这个对象负责把新的类装入正在运行的JVM。JVM给ClassLoader一个包含了待装入类(例如java.lang.Object)名字的字符串,然后由ClassLoader负责找到类文件,装入原始数据,并把它转换成一个Class对象。 用户下载的是加密过的类文件,在加密类文件装入之时进行解密,因此可以看成是一种即时解密器。由于解密后的字节码文件永远不会保存到文件系统,所以窃密者很难得到解密后的代码。 由于把原始字节码转换成Class对象的过程完全由系统负责,所以创建定制ClassLoader对象其实并不困难,只需先获得原始数据,接着就可以进行包含解密在内的任何转换。 Java密码体系和Java密码扩展 Java密码体系(JCA)和Java密码扩展(JCE)的设计目的是为Java提供与实现无关的加密函数API。它们都用factory方法来创建类的例程,然后把实际的加密函数委托给提供者指定的底层引擎,引擎中为类提供了服务提供者接口在Java中实现数据的加密/解密,是使用其内置的JCE(Java加密扩展)来实现的。Java开发工具集1.1为实现包括数字签名和信息摘要在内的加密功能,推出了一种基于供应商的新型灵活应用编程接口。Java密码体系结构支持供应商的互操作,同时支持硬件和软件实现。 Java密码学结构设计遵循两个原则: (1)算法的独立性和可靠性。 (2)实现的独立性和相互作用性。 算法的独立性是通过定义密码服务类来获得。用户只需了解密码算法的概念,而不用去关心如何实现这些概念。实现的独立性和相互作用性通过密码服务提供器来实现。密码服务提供器是实现一个或多个密码服务的一个或多个程序包。软件开发商根据一定接口,将各种算法实现后,打包成一个提供器,用户可以安装不同的提供器。安装和配置提供器,可将包含提供器的ZIP和JAR文件放在CLASSPATH下,再编辑Java安全属性文件来设置定义一个提供器。Java运行环境Sun版本时, 提供一个缺省的提供器Sun。 下面介绍DES算法及如何利用DES算法加密和解密类文件的步骤。 DES算法简介 DES(Data Encryption Standard)是发明最早的最广泛使用的分组对称加密算法。DES算法的入口参数有三个:Key、Data、Mode。

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加密算法如下:

一、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轮次迭代运算形成的初始密文

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

求C语言编写的DES加密解密源代码

从别的地方抄来的

#include "stdio.h"

#include "time.h"

#include "stdlib.h"

#define PLAIN_FILE_OPEN_ERROR -1

#define KEY_FILE_OPEN_ERROR -2

#define CIPHER_FILE_OPEN_ERROR -3

#define OK 1;

typedef char ElemType;

/* 初始置换表IP */

int IP_Table[64] = { 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,

56,48,40,32,24,16,8,0,

58,50,42,34,26,18,10,2,

60,52,44,36,28,20,12,4,

62,54,46,38,30,22,14,6};

/* 逆初始置换表IP^-1 */

int IP_1_Table[64] = {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,0,40,8,48,16,56,24};

/* 扩充置换表E */

int E_Table[48] = {31, 0, 1, 2, 3, 4,

3, 4, 5, 6, 7, 8,

7, 8,9,10,11,12,

11,12,13,14,15,16,

15,16,17,18,19,20,

19,20,21,22,23,24,

23,24,25,26,27,28,

27,28,29,30,31, 0};

/* 置换函数P */

int P_Table[32] = {15,6,19,20,28,11,27,16,

0,14,22,25,4,17,30,9,

1,7,23,13,31,26,2,8,

18,12,29,5,21,10,3,24};

/* S盒 */

int S[8][4][16] =/* 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}}};

/* 置换选择1 */

int PC_1[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};

/* 置换选择2 */

int PC_2[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,46,43,48,38,55,

33,52,45,41,49,35,28,31};

/* 对左移次数的规定 */

int MOVE_TIMES[16] = {1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1};

int ByteToBit(ElemType ch,ElemType bit[8]);

int BitToByte(ElemType bit[8],ElemType *ch);

int Char8ToBit64(ElemType ch[8],ElemType bit[64]);

int Bit64ToChar8(ElemType bit[64],ElemType ch[8]);

int DES_MakeSubKeys(ElemType key[64],ElemType subKeys[16][48]);

int DES_PC1_Transform(ElemType key[64], ElemType tempbts[56]);

int DES_PC2_Transform(ElemType key[56], ElemType tempbts[48]);

int DES_ROL(ElemType data[56], int time);

int DES_IP_Transform(ElemType data[64]);

int DES_IP_1_Transform(ElemType data[64]);

int DES_E_Transform(ElemType data[48]);

int DES_P_Transform(ElemType data[32]);

int DES_SBOX(ElemType data[48]);

int DES_XOR(ElemType R[48], ElemType L[48],int count);

int DES_Swap(ElemType left[32],ElemType right[32]);

int DES_EncryptBlock(ElemType plainBlock[8], ElemType subKeys[16][48], ElemType cipherBlock[8]);

int DES_DecryptBlock(ElemType cipherBlock[8], ElemType subKeys[16][48], ElemType plainBlock[8]);

int DES_Encrypt(char *plainFile, char *keyStr,char *cipherFile);

int DES_Decrypt(char *cipherFile, char *keyStr,char *plainFile);

/* 字节转换成二进制 */

int ByteToBit(ElemType ch, ElemType bit[8]){

int cnt;

for(cnt = 0;cnt 8; cnt++){

*(bit+cnt) = (chcnt)1;

}

return 0;

}

/* 二进制转换成字节 */

int BitToByte(ElemType bit[8],ElemType *ch){

int cnt;

for(cnt = 0;cnt 8; cnt++){

*ch |= *(bit + cnt)cnt;

}

return 0;

}

/* 将长度为8的字符串转为二进制位串 */

int Char8ToBit64(ElemType ch[8],ElemType bit[64]){

int cnt;

for(cnt = 0; cnt 8; cnt++){

ByteToBit(*(ch+cnt),bit+(cnt3));

}

return 0;

}

/* 将二进制位串转为长度为8的字符串 */

int Bit64ToChar8(ElemType bit[64],ElemType ch[8]){

int cnt;

memset(ch,0,8);

for(cnt = 0; cnt 8; cnt++){

BitToByte(bit+(cnt3),ch+cnt);

}

return 0;

}

/* 生成子密钥 */

int DES_MakeSubKeys(ElemType key[64],ElemType subKeys[16][48]){

ElemType temp[56];

int cnt;

DES_PC1_Transform(key,temp);/* PC1置换 */

for(cnt = 0; cnt 16; cnt++){/* 16轮跌代,产生16个子密钥 */

DES_ROL(temp,MOVE_TIMES[cnt]);/* 循环左移 */

DES_PC2_Transform(temp,subKeys[cnt]);/* PC2置换,产生子密钥 */

}

return 0;

}

/* 密钥置换1 */

int DES_PC1_Transform(ElemType key[64], ElemType tempbts[56]){

int cnt;

for(cnt = 0; cnt 56; cnt++){

tempbts[cnt] = key[PC_1[cnt]];

}

return 0;

}

/* 密钥置换2 */

int DES_PC2_Transform(ElemType key[56], ElemType tempbts[48]){

int cnt;

for(cnt = 0; cnt 48; cnt++){

tempbts[cnt] = key[PC_2[cnt]];

}

return 0;

}

/* 循环左移 */

int DES_ROL(ElemType data[56], int time){

ElemType temp[56];

/* 保存将要循环移动到右边的位 */

memcpy(temp,data,time);

memcpy(temp+time,data+28,time);

/* 前28位移动 */

memcpy(data,data+time,28-time);

memcpy(data+28-time,temp,time);

/* 后28位移动 */

memcpy(data+28,data+28+time,28-time);

memcpy(data+56-time,temp+time,time);

return 0;

}

/* IP置换 */

int DES_IP_Transform(ElemType data[64]){

int cnt;

ElemType temp[64];

for(cnt = 0; cnt 64; cnt++){

temp[cnt] = data[IP_Table[cnt]];

}

memcpy(data,temp,64);

return 0;

}

/* IP逆置换 */

int DES_IP_1_Transform(ElemType data[64]){

int cnt;

ElemType temp[64];

for(cnt = 0; cnt 64; cnt++){

temp[cnt] = data[IP_1_Table[cnt]];

}

memcpy(data,temp,64);

return 0;

}

/* 扩展置换 */

int DES_E_Transform(ElemType data[48]){

int cnt;

ElemType temp[48];

for(cnt = 0; cnt 48; cnt++){

temp[cnt] = data[E_Table[cnt]];

}

memcpy(data,temp,48);

return 0;

}

/* P置换 */

int DES_P_Transform(ElemType data[32]){

int cnt;

ElemType temp[32];

for(cnt = 0; cnt 32; cnt++){

temp[cnt] = data[P_Table[cnt]];

}

memcpy(data,temp,32);

return 0;

}

/* 异或 */

int DES_XOR(ElemType R[48], ElemType L[48] ,int count){

int cnt;

for(cnt = 0; cnt count; cnt++){

R[cnt] ^= L[cnt];

}

return 0;

}

/* S盒置换 */

int DES_SBOX(ElemType data[48]){

int cnt;

int line,row,output;

int cur1,cur2;

for(cnt = 0; cnt 8; cnt++){

cur1 = cnt*6;

cur2 = cnt2;

/* 计算在S盒中的行与列 */

line = (data[cur1]1) + data[cur1+5];

row = (data[cur1+1]3) + (data[cur1+2]2)

+ (data[cur1+3]1) + data[cur1+4];

output = S[cnt][line][row];

/* 化为2进制 */

data[cur2] = (output0X08)3;

data[cur2+1] = (output0X04)2;

data[cur2+2] = (output0X02)1;

data[cur2+3] = output0x01;

}

return 0;

}

/* 交换 */

int DES_Swap(ElemType left[32], ElemType right[32]){

ElemType temp[32];

memcpy(temp,left,32);

memcpy(left,right,32);

memcpy(right,temp,32);

return 0;

}

/* 加密单个分组 */

int DES_EncryptBlock(ElemType plainBlock[8], ElemType subKeys[16][48], ElemType cipherBlock[8]){

ElemType plainBits[64];

ElemType copyRight[48];

int cnt;

Char8ToBit64(plainBlock,plainBits);

/* 初始置换(IP置换) */

DES_IP_Transform(plainBits);

/* 16轮迭代 */

for(cnt = 0; cnt 16; cnt++){

memcpy(copyRight,plainBits+32,32);

/* 将右半部分进行扩展置换,从32位扩展到48位 */

DES_E_Transform(copyRight);

/* 将右半部分与子密钥进行异或操作 */

DES_XOR(copyRight,subKeys[cnt],48);

/* 异或结果进入S盒,输出32位结果 */

DES_SBOX(copyRight);

/* P置换 */

DES_P_Transform(copyRight);

/* 将明文左半部分与右半部分进行异或 */

DES_XOR(plainBits,copyRight,32);

if(cnt != 15){

/* 最终完成左右部的交换 */

DES_Swap(plainBits,plainBits+32);

}

}

/* 逆初始置换(IP^1置换) */

DES_IP_1_Transform(plainBits);

Bit64ToChar8(plainBits,cipherBlock);

return 0;

}

/* 解密单个分组 */

int DES_DecryptBlock(ElemType cipherBlock[8], ElemType subKeys[16][48],ElemType plainBlock[8]){

ElemType cipherBits[64];

ElemType copyRight[48];

int cnt;

Char8ToBit64(cipherBlock,cipherBits);

/* 初始置换(IP置换) */

DES_IP_Transform(cipherBits);

/* 16轮迭代 */

for(cnt = 15; cnt = 0; cnt--){

memcpy(copyRight,cipherBits+32,32);

/* 将右半部分进行扩展置换,从32位扩展到48位 */

DES_E_Transform(copyRight);

/* 将右半部分与子密钥进行异或操作 */

DES_XOR(copyRight,subKeys[cnt],48);

/* 异或结果进入S盒,输出32位结果 */

DES_SBOX(copyRight);

/* P置换 */

DES_P_Transform(copyRight);

/* 将明文左半部分与右半部分进行异或 */

DES_XOR(cipherBits,copyRight,32);

if(cnt != 0){

/* 最终完成左右部的交换 */

DES_Swap(cipherBits,cipherBits+32);

}

}

/* 逆初始置换(IP^1置换) */

DES_IP_1_Transform(cipherBits);

Bit64ToChar8(cipherBits,plainBlock);

return 0;

}

/* 加密文件 */

int DES_Encrypt(char *plainFile, char *keyStr,char *cipherFile){

FILE *plain,*cipher;

int count;

ElemType plainBlock[8],cipherBlock[8],keyBlock[8];

ElemType bKey[64];

ElemType subKeys[16][48];

if((plain = fopen(plainFile,"rb")) == NULL){

return PLAIN_FILE_OPEN_ERROR;

}

if((cipher = fopen(cipherFile,"wb")) == NULL){

return CIPHER_FILE_OPEN_ERROR;

}

/* 设置密钥 */

memcpy(keyBlock,keyStr,8);

/* 将密钥转换为二进制流 */

Char8ToBit64(keyBlock,bKey);

/* 生成子密钥 */

DES_MakeSubKeys(bKey,subKeys);

while(!feof(plain)){

/* 每次读8个字节,并返回成功读取的字节数 */

if((count = fread(plainBlock,sizeof(char),8,plain)) == 8){

DES_EncryptBlock(plainBlock,subKeys,cipherBlock);

fwrite(cipherBlock,sizeof(char),8,cipher);

}

}

if(count){

/* 填充 */

memset(plainBlock + count,'\0',7 - count);

/* 最后一个字符保存包括最后一个字符在内的所填充的字符数量 */

plainBlock[7] = 8 - count;

DES_EncryptBlock(plainBlock,subKeys,cipherBlock);

fwrite(cipherBlock,sizeof(char),8,cipher);

}

fclose(plain);

fclose(cipher);

return OK;

}

/* 解密文件 */

int DES_Decrypt(char *cipherFile, char *keyStr,char *plainFile){

FILE *plain, *cipher;

int count,times = 0;

long fileLen;

ElemType plainBlock[8],cipherBlock[8],keyBlock[8];

ElemType bKey[64];

ElemType subKeys[16][48];

if((cipher = fopen(cipherFile,"rb")) == NULL){

return CIPHER_FILE_OPEN_ERROR;

}

if((plain = fopen(plainFile,"wb")) == NULL){

return PLAIN_FILE_OPEN_ERROR;

}

/* 设置密钥 */

memcpy(keyBlock,keyStr,8);

/* 将密钥转换为二进制流 */

Char8ToBit64(keyBlock,bKey);

/* 生成子密钥 */

DES_MakeSubKeys(bKey,subKeys);

/* 取文件长度 */

fseek(cipher,0,SEEK_END); /* 将文件指针置尾 */

fileLen = ftell(cipher); /* 取文件指针当前位置 */

rewind(cipher); /* 将文件指针重指向文件头 */

while(1){

/* 密文的字节数一定是8的整数倍 */

fread(cipherBlock,sizeof(char),8,cipher);

DES_DecryptBlock(cipherBlock,subKeys,plainBlock);

times += 8;

if(times fileLen){

fwrite(plainBlock,sizeof(char),8,plain);

}

else{

break;

}

}

/* 判断末尾是否被填充 */

if(plainBlock[7] 8){

for(count = 8 - plainBlock[7]; count 7; count++){

if(plainBlock[count] != '\0'){

break;

}

}

}

if(count == 7){/* 有填充 */

fwrite(plainBlock,sizeof(char),8 - plainBlock[7],plain);

}

else{/* 无填充 */

fwrite(plainBlock,sizeof(char),8,plain);

}

fclose(plain);

fclose(cipher);

return OK;

}

int main()

{ DES_Encrypt("1.txt","key.txt","2.txt");

system("pause");

DES_Decrypt("2.txt","key.txt","3.txt");

getchar();

return 0;

}

des算法加密解密的实现

一.加密

DES算法处理的数据对象是一组64比特的明文串。设该明文串为m=m1m2…m64 (mi=0或1)。明文串经过64比特的密钥K来加密,最后生成长度为64比特的密文E。其加密过程图示如下:

DES算法加密过程

对DES算法加密过程图示的说明如下:待加密的64比特明文串m,经过IP置换后,得到的比特串的下标列表如下:

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

该比特串被分为32位的L0和32位的R0两部分。R0子密钥K1(子密钥的生成将在后面讲)经过变换f(R0,K1)(f变换将在下面讲)输出32位的比特串f1,f1与L0做不进位的二进制加法运算。运算规则为:

f1与L0做不进位的二进制加法运算后的结果赋给R1,R0则原封不动的赋给L1。L1与R0又做与以上完全相同的运算,生成L2,R2…… 一共经过16次运算。最后生成R16和L16。其中R16为L15与f(R15,K16)做不进位二进制加法运算的结果,L16是R15的直接赋值。

R16与L16合并成64位的比特串。值得注意的是R16一定要排在L16前面。R16与L16合并后成的比特串,经过置换IP-1后所得比特串的下标列表如下:

IP-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

经过置换IP-1后生成的比特串就是密文e.。

下面再讲一下变换f(Ri-1,Ki)。

它的功能是将32比特的输入再转化为32比特的输出。其过程如图所示:

对f变换说明如下:输入Ri-1(32比特)经过变换E后,膨胀为48比特。膨胀后的比特串的下标列表如下:

E: 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 31

膨胀后的比特串分为8组,每组6比特。各组经过各自的S盒后,又变为4比特(具体过程见后),合并后又成为32比特。该32比特经过P变换后,其下标列表如下:

P: 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

经过P变换后输出的比特串才是32比特的f (Ri-1,Ki)。

下面再讲一下S盒的变换过程。任取一S盒。见图:

在其输入b1,b2,b3,b4,b5,b6中,计算出x=b1*2+b6, y=b5+b4*2+b3*4+b2*8,再从Si表中查出x 行,y 列的值Sxy。将Sxy化为二进制,即得Si盒的输出。(S表如图所示)

至此,DES算法加密原理讲完了。在VC++6.0下的程序源代码为:

for(i=1;i=64;i++)

m1[i]=m[ip[i-1]];//64位明文串输入,经过IP置换。

下面进行迭代。由于各次迭代的方法相同只是输入输出不同,因此只给出其中一次。以第八次为例://进行第八次迭代。首先进行S盒的运算,输入32位比特串。

for(i=1;i=48;i++)//经过E变换扩充,由32位变为48位

RE1[i]=R7[E[i-1]];

for(i=1;i=48;i++)//与K8按位作不进位加法运算

RE1[i]=RE1[i]+K8[i];

for(i=1;i=48;i++)

{

if(RE1[i]==2)

RE1[i]=0;

}

for(i=1;i7;i++)//48位分成8组

{

s11[i]=RE1[i];

s21[i]=RE1[i+6];

s31[i]=RE1[i+12];

s41[i]=RE1[i+18];

s51[i]=RE1[i+24];

s61[i]=RE1[i+30];

s71[i]=RE1[i+36];

s81[i]=RE1[i+42];

}//下面经过S盒,得到8个数。S1,s2,s3,s4,s5,s6,s7,s8分别为S表

s[1]=s1[s11[6]+s11[1]*2][s11[5]+s11[4]*2+s11[3]*4+s11[2]*8];

s[2]=s2[s21[6]+s21[1]*2][s21[5]+s21[4]*2+s21[3]*4+s21[2]*8];

s[3]=s3[s31[6]+s31[1]*2][s31[5]+s31[4]*2+s31[3]*4+s31[2]*8];

s[4]=s4[s41[6]+s41[1]*2][s41[5]+s41[4]*2+s41[3]*4+s41[2]*8];

s[5]=s5[s51[6]+s51[1]*2][s51[5]+s51[4]*2+s51[3]*4+s51[2]*8];

s[6]=s6[s61[6]+s61[1]*2][s61[5]+s61[4]*2+s61[3]*4+s61[2]*8];

s[7]=s7[s71[6]+s71[1]*2][s71[5]+s71[4]*2+s71[3]*4+s71[2]*8];

s[8]=s8[s81[6]+s81[1]*2][s81[5]+s81[4]*2+s81[3]*4+s81[2]*8];

for(i=0;i8;i++)//8个数变换输出二进制

{

for(j=1;j5;j++)

{

temp[j]=s[i+1]%2;

s[i+1]=s[i+1]/2;

}

for(j=1;j5;j++)

f[4*i+j]=temp[5-j];

}

for(i=1;i33;i++)//经过P变换

frk[i]=f[P[i-1]];//S盒运算完成

for(i=1;i33;i++)//左右交换

L8[i]=R7[i];

for(i=1;i33;i++)//R8为L7与f(R,K)进行不进位二进制加法运算结果

{

R8[i]=L7[i]+frk[i];

if(R8[i]==2)

R8[i]=0;

}

[ 原创文档 本文适合中级读者 已阅读21783次 ] 文档 代码 工具

DES算法及其在VC++6.0下的实现(下)

作者:航天医学工程研究所四室 朱彦军

在《DES算法及其在VC++6.0下的实现(上)》中主要介绍了DES算法的基本原理,下面让我们继续:

二.子密钥的生成

64比特的密钥生成16个48比特的子密钥。其生成过程见图:

子密钥生成过程具体解释如下:

64比特的密钥K,经过PC-1后,生成56比特的串。其下标如表所示:

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

该比特串分为长度相等的比特串C0和D0。然后C0和D0分别循环左移1位,得到C1和D1。C1和D1合并起来生成C1D1。C1D1经过PC-2变换后即生成48比特的K1。K1的下标列表为:

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

C1、D1分别循环左移LS2位,再合并,经过PC-2,生成子密钥K2……依次类推直至生成子密钥K16。

注意:Lsi (I =1,2,….16)的数值是不同的。具体见下表:

迭代顺序 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16

左移位数 1 1 2 2 2 2 2 2 1 2 2 2 2 2 2 1

生成子密钥的VC程序源代码如下:

for(i=1;i57;i++)//输入64位K,经过PC-1变为56位 k0[i]=k[PC_1[i-1]];

56位的K0,均分为28位的C0,D0。C0,D0生成K1和C1,D1。以下几次迭代方法相同,仅以生成K8为例。 for(i=1;i27;i++)//循环左移两位

{

C8[i]=C7[i+2];

D8[i]=D7[i+2];

}

C8[27]=C7[1];

D8[27]=D7[1];

C8[28]=C7[2];

D8[28]=D7[2];

for(i=1;i=28;i++)

{

C[i]=C8[i];

C[i+28]=D8[i];

}

for(i=1;i=48;i++)

K8[i]=C[PC_2[i-1]];//生成子密钥k8

注意:生成的子密钥不同,所需循环左移的位数也不同。源程序中以生成子密钥 K8为例,所以循环左移了两位。但在编程中,生成不同的子密钥应以Lsi表为准。

三.解密

DES的解密过程和DES的加密过程完全类似,只不过将16圈的子密钥序列K1,K2……K16的顺序倒过来。即第一圈用第16个子密钥K16,第二圈用K15,其余类推。

第一圈:

加密后的结果

L=R15, R=L15⊕f(R15,K16)⊕f(R15,K16)=L15

同理R15=L14⊕f(R14,K15), L15=R14。

同理类推:

得 L=R0, R=L0。

其程序源代码与加密相同。在此就不重写。

四.示例

例如:已知明文m=learning, 密钥 k=computer。

明文m的ASCII二进制表示:

m= 01101100 01100101 01100001 01110010

01101110 01101001 01101110 01100111

密钥k的ASCII二进制表示:

k=01100011 01101111 01101101 01110000

01110101 01110100 01100101 01110010

明文m经过IP置换后,得:

11111111 00001000 11010011 10100110 00000000 11111111 01110001 11011000

等分为左右两段:

L0=11111111 00001000 11010011 10100110 R0=00000000 11111111 01110001 11011000

经过16次迭代后,所得结果为:

L1=00000000 11111111 01110001 11011000 R1=00110101 00110001 00111011 10100101

L2=00110101 00110001 00111011 10100101 R2=00010111 11100010 10111010 10000111

L3=00010111 11100010 10111010 10000111 R3=00111110 10110001 00001011 10000100

L4=00111110101100010000101110000100 R4=11110111110101111111101000111110

L5=11110111110101111111101000111110 R5=10010110011001110100111111100101

L6=10010110011001110100111111100101 R6=11001011001010000101110110100111

L7=11001011001010000101110110100111 R7=01100011110011101000111011011001

L8=01100011110011101000111011011001 R8=01001011110100001111001000000100

L9=01001011110100001111001000000100 R9=00011101001101111010111011100001

L10=00011101001101111010111011100001 R10=11101110111110111111010100000101

L11=11101110111110111111010100000101 R11=01101101111011011110010111111000

L12=01101101111011011110010111111000 R12=11111101110011100111000110110111

L13=11111101110011100111000110110111 R13=11100111111001011010101000000100

L14=11100111111001011010101000000100 R14=00011110010010011011100001100001

L15=00011110010010011011100001100001 R15=01010000111001001101110110100011

L16=01010000111001001101110110100011 R16=01111101101010000100110001100001

其中,f函数的结果为:

f1=11001010001110011110100000000011 f2=00010111000111011100101101011111

f3=00001011100000000011000000100001 f4=11100000001101010100000010111001

f5=10101000110101100100010001100001 f6=00111100111111111010011110011001

f7=11110101101010011100000100111100 f8=10000000111110001010111110100011

f9=01111110111110010010000000111000 f10=10100101001010110000011100000001

f11=01110000110110100100101100011001 f12=00010011001101011000010010110010

f13=10001010000010000100111111111100 f14=11100011100001111100100111010110

f15=10110111000000010111011110100111 f16=01100011111000011111010000000000

16个子密钥为:

K1=11110000101111101110111011010000 K2=11100000101111101111011010010101

K3=11110100111111100111011000101000 K4=11100110111101110111001000011010

K5=11101110110101110111011100100110 K6=11101111110100110101101110001011

K7=00101111110100111111101111100110 K8=10111111010110011101101101010000

K9=00011111010110111101101101000100 K10=00111111011110011101110100001001

K11=00011111011011011100110101101000 K12=01011011011011011011110100001010

K13=11011101101011011010110110001111 K14=11010011101011101010111110000000

K15=11111001101111101010011011010011 K16=11110001101111100010111000000001

S盒中,16次运算时,每次的8 个结果为:

第一次:5,11,4,1,0,3,13,9;

第二次:7,13,15,8,12,12,13,1;

第三次:8,0,0,4,8,1,9,12;

第四次:0,7,4,1,7,6,12,4;

第五次:8,1,0,11,5,0,14,14;

第六次:14,12,13,2,7,15,14,10;

第七次:12,15,15,1,9,14,0,4;

第八次:15,8,8,3,2,3,14,5;

第九次:8,14,5,2,1,15,5,12;

第十次:2,8,13,1,9,2,10,2;

第十一次:10,15,8,2,1,12,12,3;

第十二次:5,4,4,0,14,10,7,4;

第十三次:2,13,10,9,2,4,3,13;

第十四次:13,7,14,9,15,0,1,3;

第十五次:3,1,15,5,11,9,11,4;

第十六次:12,3,4,6,9,3,3,0;

子密钥生成过程中,生成的数值为:

C0=0000000011111111111111111011 D0=1000001101110110000001101000

C1=0000000111111111111111110110 D1=0000011011101100000011010001

C2=0000001111111111111111101100 D2=0000110111011000000110100010

C3=0000111111111111111110110000 D3=0011011101100000011010001000

C4=0011111111111111111011000000 D4=1101110110000001101000100000

C5=1111111111111111101100000000 D5=0111011000000110100010000011

C6=1111111111111110110000000011 D6=1101100000011010001000001101

C7=1111111111111011000000001111 D7=0110000001101000100000110111

C8=1111111111101100000000111111 D8=1000000110100010000011011101

C9=1111111111011000000001111111 D9=0000001101000100000110111011

C10=1111111101100000000111111111 D10=0000110100010000011011101100

C11=1111110110000000011111111111 D11=0011010001000001101110110000

C12=1111011000000001111111111111 D12=1101000100000110111011000000

C13=1101100000000111111111111111 D13=0100010000011011101100000011

C14=0110000000011111111111111111 D14=0001000001101110110000001101

C15=1000000001111111111111111101 D15=0100000110111011000000110100

C16=0000000011111111111111111011 D16=1000001101110110000001101000

des加密解密源代码的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于des加密算法源代码、des加密解密源代码的信息别忘了在本站进行查找喔。

版权说明:如非注明,本站文章均为 AH站长 原创,转载请注明出处和附带本文链接;

本文地址:http://ahzz.com.cn/post/20560.html


取消回复欢迎 发表评论:

分享到

温馨提示

下载成功了么?或者链接失效了?

联系我们反馈

立即下载