当前位置:首页 » 编程语言 » des算法c语言

des算法c语言

发布时间: 2023-12-10 22:09:30

① 求一个用c语言写的DES加密算法~~

using system;
using system.security.cryptography;
using system.io;
using system.text;

public class encryptstringdes {

public static void main(string);
return;
}

// 使用utf8函数加密输入参数
utf8encoding utf8encoding = new utf8encoding();
byte.tochararray());

// 方式一:调用默认的des实现方法des_csp.
des des = des.create();
// 方式二:直接使用des_csp()实现des的实体
//des_csp des = new des_csp();

// 初始化des加密的密钥和一个随机的、8比特的初始化向量(iv)
byte iv = {0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef};
des.key = key;
des.iv = iv;

// 建立加密流
symmetricstreamencryptor sse = des.createencryptor();

// 使用cryptomemorystream方法获取加密过程的输出
cryptomemorystream cms = new cryptomemorystream();

// 将symmetricstreamencryptor流中的加密数据输出到cryptomemorystream中
sse.setsink(cms);

// 加密完毕,将结果输出到控制台
sse.write(inputbytearray);
sse.closestream();

// 获取加密数据
byte);
}
console.writeline();

//上面演示了如何进行加密,下面演示如何进行解密
symmetricstreamdecryptor ssd = des.createdecryptor();
cms = new cryptomemorystream();
ssd.setsink(cms);
ssd.write(encrypteddata);
ssd.closestream();

byte decryptedchararray = utf8encoding.getchars(decrypteddata);
console.writeline("解密后数据:");
console.write(decryptedchararray);
console.writeline();
}
}

编译

d:\csharp>csc des_demo.cs
microsoft (r) c# compiler version 7.00.8905
right (c) microsoft corp 2000. all rights reserved.

运行实例:
d:\csharp>des_demo.exe 使用c#编写des加密程序的framework

加密结果:
3d 22 64 c6 57 d1 c4 c3 cf 77 ce 2f d0 e1 78 2a 4d ed 7a a8 83 f9 0e 14 e1 ba 38
7b 06 41 8d b5 e9 3f 00 0d c3 28 d1 f9 6d 17 4b 6e a7 41 68 40

② des解密算法,利用C语言解密JAVA语言加密的密码。。密钥为12345678,加密后的密文为:26d086be3a3a62fc

// C 语言 DES用的是 ECB模式, 没有填充
// 因此Java端要对应, 你的明文是 liubiao 吗?
// 另外 DES已经不安全了, 如果可以改为 3DES或者 AES吧。
public class LearnDes {

public static void main(String[] args) {
try {
System.out.println(encrypt("liubiao", "12345678"));

System.out.println(decrypt("26d086be3a3a62fc", "12345678"));
} catch (Exception e) {
e.printStackTrace();
}
}
public static String encrypt(String message, String key) throws Exception {
//Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
Cipher cipher = Cipher.getInstance("DES/ECB/NOPADDING");

DESKeySpec desKeySpec = new DESKeySpec(key.getBytes("UTF-8"));

SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
IvParameterSpec iv = new IvParameterSpec(key.getBytes("UTF-8"));
//cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);
cipher.init(Cipher.ENCRYPT_MODE, secretKey );

return toHexString(cipher.doFinal(message.getBytes("UTF-8")));
}

public static String decrypt(String message, String key) throws Exception {

byte[] bytesrc = convertHexString(message);

//Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
Cipher cipher = Cipher.getInstance("DES/ECB/NOPADDING");
DESKeySpec desKeySpec = new DESKeySpec(key.getBytes("UTF-8"));
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
IvParameterSpec iv = new IvParameterSpec(key.getBytes("UTF-8"));

//cipher.init(Cipher.DECRYPT_MODE, secretKey, iv);
cipher.init(Cipher.DECRYPT_MODE, secretKey );

byte[] retByte = cipher.doFinal(bytesrc);
return new String(retByte);
}

public static byte[] convertHexString(String ss) {
byte digest[] = new byte[ss.length() / 2];
for (int i = 0; i < digest.length; i++) {
String byteString = ss.substring(2 * i, 2 * i + 2);
int byteValue = Integer.parseInt(byteString, 16);
digest[i] = (byte) byteValue;
}

return digest;
}
public static String toHexString(byte b[]) {
StringBuffer hexString = new StringBuffer();
for (int i = 0; i < b.length; i++) {
String plainText = Integer.toHexString(0xff & b[i]);
if (plainText.length() < 2)
plainText = "0" + plainText;
hexString.append(plainText);
}

return hexString.toString();
}
}

③ DES加密算法C语言实现

#include<iostream.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_Proction();
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;i<8;i++)
for(int j=0;j<8;j++){
cin>>key_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;i<8;i++)
for(j=0;j<7;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_Proction() //生成子密钥
{
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;i<16;i++) //生成子密钥
{
int j,k;
int a[2],b[2];
int bb[28],cc[28];
for(j=0;j<4;j++)
for(k=0;k<7;k++)
c0[j][k]=c0_d0[j][k];
for(j=4;j<8;j++)
for(k=0;k<7;k++)
d0[j-4][k]=c0_d0[j][k];
for(j=0;j<4;j++)
for(k=0;k<7;k++){
bb[7*j+k]=c0[j][k];
cc[7*j+k]=d0[j][k];
}
for(j=0;j<move[i][1];j++){
a[j]=bb[j];
b[j]=cc[j];
}
for(j=0;j<28-move[i][1];j++){
bb[j]=bb[j+1];
cc[j]=cc[j+1];
}
for(j=0;j<move[i][1];j++){
bb[27-j]=a[j];
cc[27-j]=b[j];
}
for(j=0;j<28;j++){
c0[j/7][j%7]=bb[j];
d0[j/7][j%7]=cc[j];
}
for(j=0;j<4;j++) //L123--L128是把c0,d0合并成c0_d0
for(k=0;k<7;k++)
c0_d0[j][k]=c0[j][k];
for(j=4;j<8;j++)
for(k=0;k<7;k++)
c0_d0[j][k]=d0[j-4][k];
for(j=0;j<8;j++) //对Ci,Di进行PC-2置换
for(k=0;k<6;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';
cin>>encipher_decipher;
char * s;
if(encipher_decipher==1) s="明文";
else s="密文";
cout<<"请输入64位"<<s<<"(二进制):\n";
int i,j;
for(i=0;i<8;i++)
for(j=0;j<8;j++)
cin>>text[i][j];
for(i=0;i<8;i++) //进行IP变换
for(j=0;j<8;j++)
text_ip[i][j]=text[ (IP[i][j]-1)/8 ][ (IP[i][j]-1)%8 ];
}

④ des加密算法(c/c++)

des.h文件:

#ifndefCRYPTOPP_DES_H

#defineCRYPTOPP_DES_H

#include"cryptlib.h"

#include"misc.h"

NAMESPACE_BEGIN(CryptoPP)

classDES:publicBlockTransformation

{

public:

DES(constbyte*userKey,CipherDir);

voidProcessBlock(constbyte*inBlock,byte*outBlock)const;

voidProcessBlock(byte*inoutBlock)const

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

enum{KEYLENGTH=8,BLOCKSIZE=8};

unsignedintBlockSize()const{returnBLOCKSIZE;}

protected:

staticconstword32Spbox[8][64];

SecBlock<word32>k;

};

classDESEncryption:publicDES

{

public:

DESEncryption(constbyte*userKey)

:DES(userKey,ENCRYPTION){}

};

classDESDecryption:publicDES

{

public:

DESDecryption(constbyte*userKey)

:DES(userKey,DECRYPTION){}

};

classDES_EDE_Encryption:publicBlockTransformation

{

public:

DES_EDE_Encryption(constbyte*userKey)

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

voidProcessBlock(constbyte*inBlock,byte*outBlock)const;

voidProcessBlock(byte*inoutBlock)const;

enum{KEYLENGTH=16,BLOCKSIZE=8};

unsignedintBlockSize()const{returnBLOCKSIZE;}

private:

DESe,d;

};

classDES_EDE_Decryption:publicBlockTransformation

{

public:

DES_EDE_Decryption(constbyte*userKey)

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

voidProcessBlock(constbyte*inBlock,byte*outBlock)const;

voidProcessBlock(byte*inoutBlock)const;

enum{KEYLENGTH=16,BLOCKSIZE=8};

unsignedintBlockSize()const{returnBLOCKSIZE;}

private:

DESd,e;

};

classTripleDES_Encryption:publicBlockTransformation

{

public:

TripleDES_Encryption(constbyte*userKey)

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

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

voidProcessBlock(constbyte*inBlock,byte*outBlock)const;

voidProcessBlock(byte*inoutBlock)const;

enum{KEYLENGTH=24,BLOCKSIZE=8};

unsignedintBlockSize()const{returnBLOCKSIZE;}

private:

DESe1,d,e2;

};

classTripleDES_Decryption:publicBlockTransformation

{

public:

TripleDES_Decryption(constbyte*userKey)

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

d2(userKey,DECRYPTION){}

voidProcessBlock(constbyte*inBlock,byte*outBlock)const;

voidProcessBlock(byte*inoutBlock)const;

enum{KEYLENGTH=24,BLOCKSIZE=8};

unsignedintBlockSize()const{returnBLOCKSIZE;}

private:

DESd1,e,d2;

};

NAMESPACE_END

#endif

des.cpp文件:

//des.cpp-modifiedbyWeiDaifrom:

/*

*

*circa1987,'s1977

*publicdomaincode.,but

*theactualencrypt/

*Outerbridge'sDEScodeasprintedinSchneier's"AppliedCryptography."

*

*Thiscodeisinthepublicdomain.Iwouldappreciatebugreportsand

*enhancements.

*

*PhilKarnKA9Q,[email protected],August1994.

*/

#include"pch.h"

#include"misc.h"

#include"des.h"

NAMESPACE_BEGIN(CryptoPP)

/*

*Threeofthesetables,theinitialpermutation,thefinal

*,areregularenoughthat

*forspeed,wehard-codethem.They'rehereforreferenceonly.

*Also,,gensp.c,

*tobuildthecombinedSPbox,Spbox[].They'realsoherejust

*forreference.

*/

#ifdefnotdef

/*initialpermutationIP*/

staticbyteip[]={

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

};

/*finalpermutationIP^-1*/

staticbytefp[]={

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

};

/*expansionoperationmatrix*/

staticbyteei[]={

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)famousS-boxes*/

staticbytesbox[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--boxes*/

staticbytep32i[]={

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

/*permutedchoicetable(key)*/

staticconstbytepc1[]={

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

};

/*numberleftrotationsofpc1*/

staticconstbytetotrot[]={

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

};

/*permutedchoicekey(table)*/

staticconstbytepc2[]={

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

};

/*EndofDES-definedtables*/

/*bit0isleft-mostinbyte*/

staticconstintbytebit[]={

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

};

/*Setkey(initializekeyschelearray)*/

DES::DES(constbyte*key,CipherDirdir)

:k(32)

{

SecByteBlockbuffer(56+56+8);

byte*constpc1m=buffer;/*placetomodifypc1into*/

byte*constpcr=pc1m+56;/*placetorotatepc1into*/

byte*constks=pcr+56;

registerinti,j,l;

intm;

for(j=0;j<56;j++){/*convertpc1tobitsofkey*/

l=pc1[j]-1;/*integerbitlocation*/

m=l&07;/*findbit*/

pc1m[j]=(key[l>>3]&/*findwhichkeybytelisin*/

bytebit[m])/*andwhichbitofthatbyte*/

?1:0;/*andstore1-bitresult*/

}

for(i=0;i<16;i++){/*keychunkforeachiteration*/

memset(ks,0,8);/*Clearkeyschele*/

for(j=0;j<56;j++)/*rotatepc1therightamount*/

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

/**/

for(j=0;j<48;j++){/*selectbitsindivially*/

/*checkbitthatgoestoks[j]*/

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

/*maskitinifit'sthere*/

l=j%6;

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

}

}

/*Nowconverttoodd/eveninterleavedformforuseinF*/

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)//reversekeyscheleorder

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

{

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

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

}

}

/**/

/*Ccodeonlyinportableversion*/

//RichardOuterbridge'sinitialpermutationalgorithm

/*

inlinevoidIPERM(word32&left,word32&right)

{

word32work;

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

}

inlinevoidFPERM(word32&left,word32&right)

{

word32work;

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;

}

*/

//WeiDai''sinitialpermutation

//algorithm,

//(likeinMSVC)

inlinevoidIPERM(word32&left,word32&right)

{

word32work;

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;

}

inlinevoidFPERM(word32&left,word32&right)

{

word32work;

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

}

//

voidDES::ProcessBlock(constbyte*inBlock,byte*outBlock)const

{

word32l,r,work;

#ifdefIS_LITTLE_ENDIAN

l=byteReverse(*(word32*)inBlock);

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

#else

l=*(word32*)inBlock;

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

#endif

IPERM(l,r);

constword32*kptr=k;

for(unsignedi=0;i<8;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);

#ifdefIS_LITTLE_ENDIAN

*(word32*)outBlock=byteReverse(r);

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

#else

*(word32*)outBlock=r;

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

#endif

}

voidDES_EDE_Encryption::ProcessBlock(byte*inoutBlock)const

{

e.ProcessBlock(inoutBlock);

d.ProcessBlock(inoutBlock);

e.ProcessBlock(inoutBlock);

}

voidDES_EDE_Encryption::ProcessBlock(constbyte*inBlock,byte*outBlock)const

{

e.ProcessBlock(inBlock,outBlock);

d.ProcessBlock(outBlock);

e.ProcessBlock(outBlock);

}

voidDES_EDE_Decryption::ProcessBlock(byte*inoutBlock)const

{

d.ProcessBlock(inoutBlock);

e.ProcessBlock(inoutBlock);

d.ProcessBlock(inoutBlock);

}

voidDES_EDE_Decryption::ProcessBlock(constbyte*inBlock,byte*outBlock)const

{

d.ProcessBlock(inBlock,outBlock);

e.ProcessBlock(outBlock);

d.ProcessBlock(outBlock);

}

voidTripleDES_Encryption::ProcessBlock(byte*inoutBlock)const

{

e1.ProcessBlock(inoutBlock);

d.ProcessBlock(inoutBlock);

e2.ProcessBlock(inoutBlock);

}

voidTripleDES_Encryption::ProcessBlock(constbyte*inBlock,byte*outBlock)const

{

e1.ProcessBlock(inBlock,outBlock);

d.ProcessBlock(outBlock);

e2.ProcessBlock(outBlock);

}

voidTripleDES_Decryption::ProcessBlock(byte*inoutBlock)const

{

d1.ProcessBlock(inoutBlock);

e.ProcessBlock(inoutBlock);

d2.ProcessBlock(inoutBlock);

}

voidTripleDES_Decryption::ProcessBlock(constbyte*inBlock,byte*outBlock)const

{

d1.ProcessBlock(inBlock,outBlock);

e.ProcessBlock(outBlock);

d2.ProcessBlock(outBlock);

}

NAMESPACE_END

程序运行如下:

⑤ 使用C/C++语言,将DES/AES加密算法,用代码实现

哎,学校大作业吧。核心是des和aes的算法呗,自己一点点写代码量不很少呢。没时间给你写了。
不过有个很好的偷懒办法:建议lz你去找一下OpenSSL的源码。里面有AES,DES的原生C实现。现成函数。lz你直接从里面抠出来复制到你工程里就行了。。

⑥ 求des C#算法

Des算法:
Des算法是一种标准的对称加密算法,其精华就是把明文经过一系列的复杂变化后搞的面目全非,一般在不知密码的情况下要把它的恢复很难。
算法可以由四个部分描述:1.获取16个子密钥 2.初始置换置换函数ip 3.加密函数f 4.末置换函数
一下是分解动作:
1.获取16个子密钥:
密码是64位的布尔值,经过以下步骤得到16个48位的字密钥:
(1)去掉每个第八位,然后通过置换表,得到56位的子密钥
(2) 分成前后28位
(3)根据表对前后28为进行1~16轮的1或2位的循环
(4)移位后,再将两部分合并成56位,然后通过压缩置换得到48位子密钥
2.初始置换函数:
就是把64位的明文根据置换表置换成56位的明文,然后分成左右两部分
3.密码函数f
密码函数F的输入为32位的数据和48位的子密
E是扩展置换,把32位部分明文扩展成48位再与48的子密钥抑或,再经过s盒转化,成32位输出,最后再经过一个置换(p盒)就得到了密码函数的输出了。
然后把密码函数的输出跟初始置换后的左边32位抑或,结果作为新明文的后边,原右边作为新左边。
然后用16个子密钥重复上面的行为。
s盒的过程:把48位分成8个6位,取6位的第一位和最后一位,这两位组成的数作为s盒的行,其他三位作为列,知道行列后就在s盒表中查到对应的的数,这个数是4位的,就用这个4位的数代替该6位的数。所以最后出来的是32位了。
4.f函数后,重组左右部分,得到64位,再一次末置换就得到了用des加密后的密文。
DES对称加密算法归纳总结:
(i)子密钥生成:
C[0]D[0]=PC-1(K)
for 1<=i<=16
{
C[i]=LS(i)(C[i-1])
D[i]=LS(i)(D[i-1])
K[i]= PC-2(C[i]D[i])
}
(ii) 加密过程:
L[0]R[0]=IP(x)
for 1<=i<=16
{
L[i]=R[i-1]
R[i]= L[i-1]XOR f(R[i-1],K[i])
}
c=IP-1(R[16]L[16])
(iii) 解密过程:置换是逆置换
R[16]L[16]=IP(c)
for 1<=i<=16
{
R[i-1]=L[i]
L[i-1]=R[i]XOR f(L[i],K[i])
}
x=IP-1(L[0]R[0])源码
public static string DESEncrypt(string pToEncrypt, string sKey)
{
DESCryptoServiceProvider des = new DESCryptoServiceProvider();
byte[] inputByteArray = Encoding.Default.GetBytes(pToEncrypt);
des.Key = ASCIIEncoding.ASCII.GetBytes(sKey);
des.IV = ASCIIEncoding.ASCII.GetBytes(sKey);
MemoryStream ms = new MemoryStream();
CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write);
cs.Write(inputByteArray, 0, inputByteArray.Length);
cs.FlushFinalBlock();
StringBuilder ret = new StringBuilder();
foreach (byte b in ms.ToArray())
{
ret.AppendFormat("{0:X2}", b);
}
ret.ToString();
return ret.ToString();
} ///DES解密
public static string DESDecrypt(string pToDecrypt, string sKey)
{
DESCryptoServiceProvider des = new DESCryptoServiceProvider();
byte[] inputByteArray = new byte[pToDecrypt.Length / 2];
for (int x = 0; x < pToDecrypt.Length / 2; x++)
{
int i = (Convert.ToInt32(pToDecrypt.Substring(x * 2, 2), 16));
inputByteArray[x] = (byte)i;
} des.Key = ASCIIEncoding.ASCII.GetBytes(sKey);
des.IV = ASCIIEncoding.ASCII.GetBytes(sKey);
MemoryStream ms = new MemoryStream();
CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write);
cs.Write(inputByteArray, 0, inputByteArray.Length);
try
{
cs.FlushFinalBlock();
StringBuilder ret = new StringBuilder(); }
catch {
MessageBox.Show("溢出,解密有误");
return "";
}
return System.Text.Encoding.Default.GetString(ms.ToArray());
} /// <summary>
// TripleDES解密
/// </summary>
public static string TripleDESDecrypt(string encryptedString, string key)
{
if (encryptedString.Equals(string.Empty))
{
return encryptedString;
}
tdes = new (); //将秘钥编码成为二进制数组
PasswordDeriveBytes derive = new PasswordDeriveBytes(key, null);
byte[] tdesIV = new byte[8];
byte[] btaKey = derive.CryptDeriveKey("TripleDES", "SHA1", 0, tdesIV); //从字符串转换为字节组
byte[] btaCode = System.Convert.FromBase64String(encryptedString); tdes.Mode = CipherMode.ECB;
MemoryStream ms = new MemoryStream(btaCode); CryptoStream encStream = new CryptoStream(ms, tdes.CreateDecryptor(btaKey, tdesIV), CryptoStreamMode.Read);
StreamReader sr = new StreamReader(encStream, System.Text.Encoding.Unicode);
string strtmp = sr.ReadToEnd();
sr.Close();
encStream.Close(); return strtmp;
} /// <summary>
/// TripleDES加密
/// </summary>
public static string TripleDESEcrypt(string plainString, string key)
{
if (plainString.Equals(string.Empty))
{
return plainString;
} tdes = new (); //将秘钥编码成为二进制数组
PasswordDeriveBytes derive = new PasswordDeriveBytes(key, null);
byte[] tdesIV = new byte[8];
byte[] btaKey = derive.CryptDeriveKey("TripleDES", "SHA1", 0, tdesIV); //从字符串转换为字节组
byte[] btaCode = Encoding.Unicode.GetBytes(plainString); tdes.Mode = CipherMode.ECB;
MemoryStream ms = new MemoryStream(); CryptoStream encStream = new CryptoStream(ms, tdes.CreateEncryptor(btaKey, tdesIV), CryptoStreamMode.Write);
encStream.Write(btaCode, 0, btaCode.Length);
encStream.FlushFinalBlock();
encStream.Close(); //再转换为一个字符串
return System.Convert.ToBase64String(ms.ToArray());
}

⑦ 如何用C实现3DES算法..

3DES算法C语言实现,有注释! http://tech.cuit.e.cn/forum/thread-2448-1-1.html

⑧ DES算法实现

完成一个DES 算法的 详细设计 ,内容包括:

DES(Data Encryption Standard)是一种用于电子数据加密的对称密钥块加密算法 .它以64位为分组长度,64位一组的明文作为算法的输入,通过一系列复杂的操作,输出同样64位长度的密文。DES 同样采用64位密钥,但由于每8位中的最后1位用于奇偶校验,实际有效密钥长度为56位。密钥可以是任意的56位的数,且可随时改变。

DES 使用加密密钥定义变换过程,因此算法认为只有持有加密所用的密钥的用户才能解密密文。DES的两个重要的安全特性是混淆和扩散。其中 混淆 是指通过密码算法使明文和密文以及密钥的关系非常复杂,无法从数学上描述或者统计。 扩散 是指明文和密钥中的每一位信息的变动,都会影响到密文中许多位信息的变动,从而隐藏统计上的特性,增加密码的安全。

DES算法的基本过程是换位和置换。如图,有16个相同的处理阶段,称为轮。还有一个初始和最终的排列,称为 IP 和 FP,它们是反向的 (IP 取消 FP 的作用,反之亦然)。

在主轮之前,块被分成两个32位的一半和交替处理;这种纵横交错的方案被称为Feistel 方法。Feistel 结构确保了解密和加密是非常相似的过程——唯一的区别是在解密时子键的应用顺序是相反的。其余的算法是相同的。这大大简化了实现,特别是在硬件中,因为不需要单独的加密和解密算法。

符号表示异或(XOR)操作。Feistel 函数将半块和一些键合在一起。然后,将Feistel 函数的输出与块的另一半组合在一起,在下一轮之前交换这一半。在最后一轮之后,两队交换了位置;这是 Feistel 结构的一个特性,使加密和解密过程类似。

IP 置换表指定64位块上的输入排列。其含义如下:输出的第一个比特来自输入的第58位;第二个位来自第50位,以此类推,最后一个位来自第7位输入。

最后的排列是初始排列的倒数。

展开函数被解释为初始排列和最终排列。注意,输入的一些位在输出时是重复的;输入的第5位在输出的第6位和第8位中都是重复的。因此,32位半块被扩展到48位。

P排列打乱了32位半块的位元。

表的“左”和“右”部分显示了来自输入键的哪些位构成了键调度状态的左和右部分。输入的64位中只有56位被选中;剩下的8(8、16、24、32、40、48、56、64)被指定作为奇偶校验位使用。

这个排列从56位键调度状态为每轮选择48位的子键。

这个表列出了DES中使用的8个S-box,每个S-box用4位的输出替换6位的输入。给定一个6位输入,通过使用外部的两个位选择行,以及使用内部的四个位选择列,就可以找到4位输出。例如,一个输入“011011”有外部位“01”和内部位“1101”。第一行为“00”,第一列为“0000”,S-box S5对应的输出为“1001”(=9),即第二行第14列的值。

DES算法的基本流程图如下:

DES算法是典型的对称加密算法,在输入64比特明文数据后,通过输入64比特密钥和算法的一系列加密步骤后,可以得到同样为64比特的密文数据。反之,我们通过已知的密钥,可以将密文数据转换回明文。 我们将算法分为了三大块:IP置换、16次T迭代和IP逆置换 ,加密和解密过程分别如下:

实验的设计模式是自顶向下的结构,用C语言去分别是先各个函数的功能,最后通过主函数将所有函数进行整合,让算法更加清晰客观。

通过IP置换表,根据表中所示下标,找到相应位置进行置换。

对于16次 迭代,我们先将传入的经过 IP 混淆过的64位明文的左右两部分,分别为32位的 和32位的 。之后我们将 和 进行交换,得到作为IP逆置换的输入:

子密钥的生成,经历下面一系列步骤:首先对于64位密钥,进行置换选择,因为将用户输入的64 位经历压缩变成了56位,所以我们将左面和右面的各28位进行循环位移。左右两部分分别按下列规则做循环移位:当 ,循环左移1位;其余情况循环左移2位。最后将得到的新的左右两部分进行连接得到56位密钥。

对半块的 Feistel 操作分为以下五步:

如上二图表明,在给出正确的密码后,可以得到对应的明文。

若密码错误,将解码出错误答案。

【1】 Data Encryption Standard

【2】 DES算法的详细设计(简单实现)

【3】 深入理解并实现DES算法

【4】 DES算法原理完整版

【5】 安全体系(一)—— DES算法详解

⑨ 求C或C++的DES加密算法

/* d3des.h -
*
* Headers and defines for d3des.c
* Graven Imagery, 1992.
*
* Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge
* (GEnie : OUTER; CIS : [71755,204])
*/

#define D2_DES /* include double-length support */
#define D3_DES /* include triple-length support */

#ifdef D3_DES
#ifndef D2_DES
#define D2_DES /* D2_DES is needed for D3_DES */
#endif
#endif

#define EN0 0 /* MODE == encrypt */
#define DE1 1 /* MODE == decrypt */

/* A useful alias on 68000-ish machines, but NOT USED HERE. */

typedef union {
unsigned long blok[2];
unsigned short word[4];
unsigned char byte[8];
} M68K;

extern void deskey(unsigned char *, short);
/* hexkey[8] MODE
* Sets the internal key register according to the hexadecimal
* key contained in the 8 bytes of hexkey, according to the DES,
* for encryption or decryption according to MODE.
*/

extern void usekey(unsigned long *);
/* cookedkey[32]
* Loads the internal key register with the data in cookedkey.
*/

extern void cpkey(unsigned long *);
/* cookedkey[32]
* Copies the contents of the internal key register into the storage
* located at &cookedkey[0].
*/

extern void des(unsigned char *, unsigned char *);
/* from[8] to[8]
* Encrypts/Decrypts (according to the key currently loaded in the
* internal key register) one block of eight bytes at address 'from'
* into the block at address 'to'. They can be the same.
*/

#ifdef D2_DES

#define desDkey(a,b) des2key((a),(b))
extern void des2key(unsigned char *, short);
/* hexkey[16] MODE
* Sets the internal key registerS according to the hexadecimal
* keyS contained in the 16 bytes of hexkey, according to the DES,
* for DOUBLE encryption or decryption according to MODE.
* NOTE: this clobbers all three key registers!
*/

extern void Ddes(unsigned char *, unsigned char *);
/* from[8] to[8]
* Encrypts/Decrypts (according to the keyS currently loaded in the
* internal key registerS) one block of eight bytes at address 'from'
* into the block at address 'to'. They can be the same.
*/

extern void D2des(unsigned char *, unsigned char *);
/* from[16] to[16]
* Encrypts/Decrypts (according to the keyS currently loaded in the
* internal key registerS) one block of SIXTEEN bytes at address 'from'
* into the block at address 'to'. They can be the same.
*/

extern void makekey(char *, unsigned char *);
/* *password, single-length key[8]
* With a double-length default key, this routine hashes a NULL-terminated
* string into an eight-byte random-looking key, suitable for use with the
* deskey() routine.
*/

#define makeDkey(a,b) make2key((a),(b))
extern void make2key(char *, unsigned char *);
/* *password, double-length key[16]
* With a double-length default key, this routine hashes a NULL-terminated
* string into a sixteen-byte random-looking key, suitable for use with the
* des2key() routine.
*/

#ifndef D3_DES /* D2_DES only */

#define useDkey(a) use2key((a))
#define cpDkey(a) cp2key((a))

extern void use2key(unsigned long *);
/* cookedkey[64]
* Loads the internal key registerS with the data in cookedkey.
* NOTE: this clobbers all three key registers!
*/

extern void cp2key(unsigned long *);
/* cookedkey[64]
* Copies the contents of the internal key registerS into the storage
* located at &cookedkey[0].
*/

#else /* D3_DES too */

#define useDkey(a) use3key((a))
#define cpDkey(a) cp3key((a))

extern void des3key(unsigned char *, short);
/* hexkey[24] MODE
* Sets the internal key registerS according to the hexadecimal
* keyS contained in the 24 bytes of hexkey, according to the DES,
* for DOUBLE encryption or decryption according to MODE.
*/

extern void use3key(unsigned long *);
/* cookedkey[96]
* Loads the 3 internal key registerS with the data in cookedkey.
*/

extern void cp3key(unsigned long *);
/* cookedkey[96]
* Copies the contents of the 3 internal key registerS into the storage
* located at &cookedkey[0].
*/

extern void make3key(char *, unsigned char *);
/* *password, triple-length key[24]
* With a triple-length default key, this routine hashes a NULL-terminated
* string into a twenty-four-byte random-looking key, suitable for use with
* the des3key() routine.
*/

#endif /* D3_DES */
#endif /* D2_DES */

⑩ 用C语言来实现DES加密算法(很急)两天内

DES虽然不难但是挺繁复的,代码如下,关键点都有英文解释,仔细看。各个函数的功能都可以从函数名看出来。

#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 schele 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 schele */
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 indivially */
/* 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 schele 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[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);
}

热点内容
搭建300人上网的服务器 发布:2025-01-24 15:23:01 浏览:280
流控源码 发布:2025-01-24 15:09:51 浏览:476
火山服务器升级什么时候完成 发布:2025-01-24 15:08:38 浏览:246
android版本设置 发布:2025-01-24 15:08:26 浏览:723
python打印机打印图片 发布:2025-01-24 14:59:49 浏览:227
javascript设计模式源码 发布:2025-01-24 14:49:07 浏览:908
linqtosql查询 发布:2025-01-24 14:48:57 浏览:120
华为手机更换开机密码如何操作 发布:2025-01-24 14:43:15 浏览:699
快手等待上传 发布:2025-01-24 14:41:37 浏览:380
apache和php7 发布:2025-01-24 14:32:26 浏览:892