还是DES算法问题

wyj1974 2004-10-25 11:36:48
我的加密字符串是‘520338423926554’
经过MD5处理后变成Byte型:“93 58 176 184 87 49 235 244 222 250 10 179 19 62 4 151”
Byte转换为字符串型:“]:案W1媵搡
?>”


加密密匙是:“8D20FDA”

使用VC的Des加密算法的结果是:
[0] 66 'B'
[1] 87 'W'
[2] 138 '?
[3] 22 ''
[4] 77 'M'
[5] 139 '?
[6] 116 't'
[7] 13 '
'
[8] 27 ''
[9] 187 '?
[10] 20 ''
[11] 202 '?
[12] 78 'N'
[13] 252 '?
[14] 203 '?
[15] 250 '?

使用Delphi的Des加密算法的结果是:
55
53
68
53
50
51
67
55
56
57
54
67
54
57
69
54
48
68
51
52
65
69
66
56
68
53
69
52
53
53
66
56
0


有哪位大侠可以帮我分析一下!或者能在Delphi中实现VC的效果!
...全文
413 42 打赏 收藏 转发到动态 举报
写回复
用AI写文章
42 条回复
切换为时间正序
请发表友善的回复…
发表回复
wyj1974 2004-10-26
  • 打赏
  • 举报
回复
如果需要可以向我索取,我还没有测试其正确性
wyj1974 2004-10-26
  • 打赏
  • 举报
回复
我现在找到了一个DLL
头文件:
#ifndef _MODULE_DES3_H_
#define _MODULE_DES3_H_
/*
* des3 - NBS Data Encryption Standard Library
*
* Copyright (c) 1992,93,94 by SWS. All Rights Reserved.
* Stefan Wolf Software; Gartenstr 22; D-61449 Steinbach/Ts.
* FAX: +49 (0) 6171 980483; CI$ Email: 100111,140
*
* Synopsis: desinit(key)
* Description: intializes all arrays and permutation tables for
* single DES
* Input: key - 64-bit DES key
* Output: 0 if OK; >0 if a (semi) weak was selected
*
* Synopsis: des3init(key)
* Description: intializes all arrays and permutation tables for
* triple DES
* Input: key - 128-bit DES key
* Output: 0 if OK; >0 if a (semi) weak was selected
*
* Synopsis: ecbXcode(inblock,outblock)
* Description: encrypts (X=en) or decrypts (X=de) 64-bit inblock to
* 64-bit outblock using single DES in ECB mode
* Input: inblock - pointer to 64-bit buffer of input data
* outblock - pointer to 64-bit buffer for output data
* Output: 0 if OK
*
* Synopsis: ecb3Xcode(inblock,outblock)
* Description: encrypts (X=en) or decrypts (X=de) 64-bit inblock to
* 64-bit outblock using triple DES in ECB mode
* Input: inblock - pointer to 64-bit buffer of input data
* outblock - pointer to 64-bit buffer for output data
* Output: 0 if OK
*
* Synopsis: cbcXcode(inblock,outblock,ivec)
* Description: encrypts (X=en) or decrypts (X=de) 64-bit inblock to
* 64-bit outblock using single DES in CBC mode
* Input: inblock - pointer to 64-bit buffer of input data
* outblock - pointer to 64-bit buffer for output data
* ivec - pointer to 64-bit initilization vector
* Output: 0 if OK
*
* Synopsis: cbc3Xcode(inblock,outblock,ivec)
* Description: encrypts (X=en) or decrypts (X=de) 64-bit inblock to
* 64-bit outblock using triple DES in CBC mode
* Input: inblock - pointer to 64-bit buffer of input data
* outblock - pointer to 64-bit buffer for output data
* ivec - pointer to 64-bit initilization vector
* Output: 0 if OK
*
*/

typedef unsigned char uchar;

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

#if defined(WIN16)
#define DECL int far pascal
#define UCHAR uchar far
#endif /* WIN16 */

#if defined(WIN32)
/* remove pascal for MS VC */
#define DECL int pascal
#define UCHAR uchar
#endif /* WIN32 */

#if !defined(WIN16) && !defined(WIN32)
#define DECL int
#define UCHAR uchar
#endif /* !WIN16 && !WIN32 */

DECL desinit(UCHAR *key1);
DECL ecbencode(UCHAR *inblock, UCHAR *outblock);
DECL ecbdecode(UCHAR *inblock, UCHAR *outblock);
DECL cbcencode(UCHAR *inblock, UCHAR *outblock, UCHAR *ivec);
DECL cbcdecode(UCHAR *inblock, UCHAR *outblock, UCHAR *ivec);
DECL des3init(UCHAR *key3);
DECL ecb3encode(UCHAR *inblock, UCHAR *outblock);
DECL ecb3decode(UCHAR *inblock, UCHAR *outblock);
DECL cbc3encode(UCHAR *inblock, UCHAR *outblock, UCHAR *ivec);
DECL cbc3decode(UCHAR *inblock, UCHAR *outblock, UCHAR *ivec);

#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* _MODULE_DES3_H_ */
ksaiy 2004-10-25
  • 打赏
  • 举报
回复
好的。我正在分析....
你等等.
wyj1974 2004-10-25
  • 打赏
  • 举报
回复
我也使用过你的代码,结果仍是不一样!
其中的一个:
http://blog.csdn.net/liuove/archive/2004/09/09/99826.aspx
ksaiy 2004-10-25
  • 打赏
  • 举报
回复
那Delphi是否是用我给你贴出来的那个?
如果不是的话.你把代码也贴出来吧.
wyj1974 2004-10-25
  • 打赏
  • 举报
回复
就是上面的东东
ksaiy 2004-10-25
  • 打赏
  • 举报
回复
你把VC代码打个包给我下载.我好帮你分析.......
wyj1974 2004-10-25
  • 打赏
  • 举报
回复
static int perm32(char *inblock, char *outblock) /* 单纯换位*/
/* of the f crypto function */
{
register int j;

register char *ib, *ob;
register char *q;

ob = outblock; /* 把输出的块清零*/
*ob++ = 0; *ob++ = 0; *ob++ = 0; *ob++ = 0;
ib=inblock;
for (j=0; j<4; j++, ib++) /* 输入的每一字节*/
{
q = p32[j][*ib & 0377];
ob = outblock; /* 每一输出的字节*/
*ob++ |= *q++;
*ob++ |= *q++;
*ob++ |= *q++;
*ob++ |= *q++;
}

return 0;
}

static int expand(char *right, char *bigright) /* 用E变换矩阵完成32---48扩展换位*/
/* right 32 bit, bigright 48 bit */
{
register char *bb, *r, r0, r1, r2, r3;

bb = bigright;
r = right; r0 = *r++; r1 = *r++; r2 = *r++; r3 = *r++;
*bb++ = ((r3 & 0001) << 7) | /* 32 */
((r0 & 0370) >> 1) | /* 1 2 3 4 5 */
((r0 & 0030) >> 3); /* 4 5 */
*bb++ = ((r0 & 0007) << 5) | /* 6 7 8 */
((r1 & 0200) >> 3) | /* 9 */
((r0 & 0001) << 3) | /* 8 */
((r1 & 0340) >> 5); /* 9 10 11 */
*bb++ = ((r1 & 0030) << 3) | /* 12 13 */
((r1 & 0037) << 1) | /* 12 13 14 15 16 */
((r2 & 0200) >> 7); /* 17 */
*bb++ = ((r1 & 0001) << 7) | /* 16 */
((r2 & 0370) >> 1) | /* 17 18 19 20 21 */
((r2 & 0030) >> 3); /* 20 21 */
*bb++ = ((r2 & 0007) << 5) | /* 22 23 24 */
((r3 & 0200) >> 3) | /* 25 */
((r2 & 0001) << 3) | /* 24 */
((r3 & 0340) >> 5); /* 25 26 27 */
*bb++ = ((r3 & 0030) << 3) | /* 28 29 */
((r3 & 0037) << 1) | /* 28 29 30 31 32 */
((r0 & 0200) >> 7); /* 1 */

return 0;
}

static int contract(char *in48, char *out32) /* 48位经s盒后,输出32位*/
{
register char *c;
register char *i;
register int i0, i1, i2, i3, i4, i5;

i = in48;
i0 = *i++; i1 = *i++; i2 = *i++; i3 = *i++; i4 = *i++; i5 = *i++;
c = out32;
*c++ = s[0][07777 & ((i0 << 4) | ((i1 >> 4) & 017 ))];
*c++ = s[1][07777 & ((i1 << 8) | ( i2 & 0377 ))];
*c++ = s[2][07777 & ((i3 << 4) | ((i4 >> 4) & 017 ))];
*c++ = s[3][07777 & ((i4 << 8) | ( i5 & 0377 ))];

return 0;
}

} // extern "C"


/************************ 以上是DES 的全部算法************************/
#if 0

char *inname, *outname;
FILE *infile, *outfile;

int encrypting;
char buf[512];
char keyx[9],keyy[9];



char *malloc(), *strcpy(), *strcat();

main(argc, argv)
int argc; char *argv[];
{ register char *u;
char *filename;

if (argc < 2) /* 命令行是否给出了文件名? */
{ fprintf(stderr, "Usage: des file ...\n");
exit(1);
}

for (++argv; --argc; ++argv)
{ inname = *argv;
outname = filename = malloc((unsigned) strlen(inname) + 5);
strcpy(filename, inname);
u = &filename[strlen(filename) - 4]; /* 检查最后4个字符*/

encrypting = (strcmp(".des", u) != 0);
if (!encrypting) *u = 0; /* 解密时输出文件去掉.des*/
else strcat(filename, ".des"); /* 加密时给输出文件加上.des*/

if ((infile = fopen(inname, "rb")) == NULL)
{ fprintf(stderr,"Can't read %s.\n", inname);
exit(1);
}
if ((outfile = fopen(outname, "rb")) != NULL)
{ fprintf(stderr, "%s would be overwritten.\n",outname);
exit(1);
}
if ((outfile = fopen(outname, "wb")) == NULL)
{ fprintf(stderr,"Can't write %s.\n", outname);
exit(1);
}

key_get("Type password for ");
for (;;)
{ strcpy(keyx, keyy);
key_get("Verify password for ");
if (strcmp(keyx, keyy) == 0) break;
}
desinit(keyx); /*建立用于des运算的矩阵*/

if (pfile() == 0) unlink(inname);
else fprintf(stderr,
"%s: I/O Error -- File unchanged\n", inname);

fclose(outfile);
fclose(infile);
}
exit(0);
}

key_get(mes) /*输入密码*/
char *mes;
{ register int i, j;
char linebuf[256];
int count;

// for (i=0; i<14; i++) keyy[i]=0;

printf("%s%s: ", mes, inname);
fflush(stdout); /*使用read(),fread()前先刷新文件*/

count = read(0, linebuf, 256); /* 输入密码*/
printf("\n");


linebuf[count] = 0; /* 添加一个0作为字符串的结束*/
if (linebuf[count-1] == '\n')
{ linebuf[count-1] = 0; /*把"\n"变成0*/
count--;
}
if (count > 8) count = 8; /* 只取 8 字节 */
for (i = j = 0; count--;)
keyy[i++] = linebuf[j++];
}

pfile() /* 文件加密处理*/
{ register int m, nsave;
register char *b;
int j;

while (m = fread(buf, 1, 512, infile))
{
if ((nsave = m) < 0) /* 读出错*/
return(-1);
for (b=buf; m>0;m -= 8, b += 8) /* 加密解密一个缓冲区的块*/
{ if (encrypting)
{ if (m<8) /* 不够一块---64 bits */
{ for (j=0; j<8-m; j++)
b[m+j]=garbage(); /* 填充不够一块的部分*/
nsave += 8-m; /* 把nave凑成8的整数倍*/
}
else j=0; /* 不足8字节时的缺额数量j=8-m*/
endes(b,b);
}
else /* 解密*/
{ if (m < 8) deout(b, 1); /* 最后的几个字节*/
else
{ dedes(b, b); /* 解密一个块*/
deout(b, 0); /*输出到文件*/
}
}
}
if (encrypting) if (fwrite(buf, 1, nsave, outfile) != nsave)
return(-1);
}
/* 加密解密文件完成*/
if (encrypting) fputc(8 - j, outfile); /* 8-j=最后一个块的有效字节数*/
return(0);
}

int outcount = 0;

deout(block,flag) /* 根据flag标志来决定输出到文件的内容*/
char *block,flag; /* char*block 64-bit 块, flag=1:处理的块是文件的最后的块
flag=0:处理的块不是文件的最后的块*/
{ static char last[8]; /*static char last[8] 前一个输入块,静态变量,初始化为零*/
register int i;

if (flag) /* 输出的最后的几个字节*/
{
fwrite(last, 1, block[0] & 0377, outfile); /*block[0]包含内容"8-j*/
return;
}
if (outcount++) /* 以前是否处理过块,即输入的加密文件长度不到8字节*/
fwrite(last, 1, 8, outfile);
for (i = 0; i < 8; i++) last[i] = block[i]; /* 复制块*/
}

garbage() /* 产生一些数字用以填充不足8字节的块*/
/*产生数据随机性大一些,加密效果会更好*/
{
return 0;
}
#endif
ksaiy 2004-10-25
  • 打赏
  • 举报
回复
你等等.我正在帮你分析着.
wyj1974 2004-10-25
  • 打赏
  • 举报
回复
int desinit(char *key) /* 初始化各种变换矩阵*/
{
perminit(iperm,ip);
perminit(fperm,fp);
kinit(key);
sinit();
p32init();
return 0;
}

static int bytebit[]
= { 0200,0100,040,020,010,04,02,01 };

static int nibblebit[] = { 010,04,02,01 };

static sinit() /* 初始化s1-s8矩阵*/
{
register int i,j;

for (i=0; i<4; i++) /* 48位按四个12位(一个半字节)来输入*/
for (j=0; j<4096; j++)
s[i][j]=(getcomp(i*2,j>>6)<<4) |
(017&getcomp(i*2+1,j&077)); /*每个s项为一个字节,存有两个体代数*/

return 0;
}

static int getcomp(int k, int v) /* 用s[k]盒对v进行6bit~4bit的数据压缩*/
{
register int i,j;

i=((v&040)>>4)|(v&1); /*i为每个s盒的行号改行号由v的第一位和最后一位组成*/
j=(v&037)>>1; /* j位s盒的列号,该列号由v的中间四位组成*/
return (int) si[k][(i<<4)+j]; /* 返回对v压缩后的值*/
}

static int kinit(char *key) /* 初始化密钥的变换矩阵的中间过渡矩阵*/
/* 64 bits */
{
register int i,j,l;
int m;

for (j=0; j<56; j++)
{
l=pc1[j]-1;
m = l & 07;
pc1m[j]=(key[l>>3] & bytebit[m]) ? 1 : 0;
/*key[l>>3]确定第1位在char key[8]中的哪一个字节中,
char pc1m[56]是完成pc-1型换位的变换矩阵*/
}
for (i=0; i<16; i++) /* 共生成16个密钥*/
for (j=0; j<6; j++) /* 密钥kn的每一个字节*/
kn[i][j]=0;
for (i=0; i<16; i++)
{
for (j=0; j<56; j++)
pcr[j] = pc1m[(l=j+totrot[i])<(j<28? 28 : 56) ? l: l-28];
/* pcr[j]是每次进行循环左移位后的pc1m[]矩阵*/
for (j=0; j<48; j++)
if (pcr[pc2[j]-1])
{
l= j & 07;
kn[i][j>>3] |= bytebit[l];/*共16个密钥i~[0,16],每个密钥6字节j>>3~[0,5]*/
}
}

return 0;
}

static p32init() /* 初始化32bit换位表的中间过渡矩阵*/
{
register int l, j, k;
int i,m;

for (i=0; i<4; i++) /* 以字节为单位输入,i为字节在输入矩阵中的位置*/
for (j=0; j<256; j++) /* j为所输入字节的可能值[0~256]*/
for (k=0; k<4; k++)
p32[i][j][k]=0;
for (i=0; i<4; i++)
for (j=0; j<256; j++)
for (k=0; k<32; k++)
{
l=p32i[k]-1;
if ((l>>3)!=i)
continue;
if (!(j&bytebit[l&07]))
continue;
m = k & 07;
p32[i][j][k>>3] |= bytebit[m];
}

return 0;
}

static int perminit(char perm[16][16][8], char p[64]) /* 初始化换位表*/
/* 64-bit, 完成换位的中间的过渡矩阵*/
{
register int l, j, k;
int i,m;

for (i=0; i<16; i++) /* 每一个输入的4 bit*/
for (j=0; j<16; j++) /* 每一个4 bit的可能值~[0,16]*/
for (k=0; k<8; k++) /* 每一个屏蔽字*/
perm[i][j][k]=0; /* 过渡矩阵清零*/
for (i=0; i<16; i++) /* 每一个输入的4 bit*/
for (j = 0; j < 16; j++) /* 每一个4 bit的可能值~[0,16]*/
for (k = 0; k < 64; k++) /* 每一个输出bit的位置*/
{
l = p[k] - 1; /* p[k]最小值为l,l从0开始*/
if ((l >> 2) != i) /* l~[0,63],每四位一组,共十六组,因此要l>>2*/
continue;
if (!(j & nibblebit[l & 3])) /*确定第l~[0,63]位是一个四位组中的第几位*/
continue;
m = k & 07; /*确定第k~[0,63]位是一个字节中的第几位*/
perm[i][j][k>>3] |= bytebit[m];
}

return 0;
}

static int iter(int num, char *inblock, char *outblock) /* 完成第num层的变换*/
/* 64 bits */
{
char fret[4]; /* 放置f(R[i-1],key)的返回值*/
register char *ib, *ob, *fb;


ob = outblock;
ib = &inblock[4]; /*右边32位*/
f(ib, num, fret);
*ob++ = *ib++; /* L[i] = R[i-1] */
*ob++ = *ib++;
*ob++ = *ib++;
*ob++ = *ib++;
ib = inblock; fb = fret; /* R[i]=L[i] XOR f(R[i-1],key) */
*ob++ = *ib++ ^ *fb++;
*ob++ = *ib++ ^ *fb++;
*ob++ = *ib++ ^ *fb++;
*ob++ = *ib++ ^ *fb++;

return 0;
}

static int f(char *right, int num, char *fret) /* 完成num层的f()函数*/
/* 32 bits */
{
register char *kb, *rb, *bb;
char bigright[6];
char result[6];
char preout[4];

kb = kn[num];
bb = bigright;
rb = result;
expand(right,bb); /*扩展成48bit*/
*rb++ = *bb++ ^ *kb++;
*rb++ = *bb++ ^ *kb++; /*Kn与Rn异或操作*/
*rb++ = *bb++ ^ *kb++;
*rb++ = *bb++ ^ *kb++;
*rb++ = *bb++ ^ *kb++;
*rb++ = *bb++ ^ *kb++;
contract(result,preout); /*用s盒得到32bit输出*/
perm32(preout,fret); /*最后换位*/

return 0;
}

wyj1974 2004-10-25
  • 打赏
  • 举报
回复
VC源码:
extern "C"
{

int perminit(char perm[16][16][8], char p[64]);
int permute(char *inblock, char perm[16][16][8], char *outblock);
int iter(int num, char *inblock, char *outblock);
int kinit(char *key);
int sinit();
int p32init();
int getcomp(int k, int v);
int f(char *right, int num, char *fret);
int expand(char *right, char *bigright);
int contract(char *in48, char *out32);
int perm32(char *inblock, char *outblock);






static char iperm[16][16][8],fperm[16][16][8];
static char s[4][4096];
static char p32[4][256][4];
static char kn[16][6]; /* 密钥*/


int endes(char *inblock, char*outblock) /* 加密一个64-bit块*/
{
char iters[17][8];
char swap[8]; /* 放置左右交换的值*/
register int i;
register char *s, *t;

permute(inblock,iperm,iters[0]);
for (i=0; i<16; i++) /* 完成1~16层的交换*/
iter(i,iters[i],iters[i+1]);
/* iters[0][0]~iters[0][8]操作后放到iters[1][0]~iters[1][8]
iters[1][0]~iters[1][8]操作后放到iters[2][0]~iters[2][8]...以此类推*/
s = swap; t = &iters[16][4];
*s++ = *t++; *s++ = *t++; *s++ = *t++; *s++ = *t++;
t = &iters[16][0];
*s++ = *t++; *s++ = *t++; *s++ = *t++; *s++ = *t++;
permute(swap,fperm,outblock);

return 0;
}

int dedes(char *inblock, char *outblock) /* 解密一个64-bit 块*/
{
char iters[17][8];
char swap[8];
register int i;
register char *s, *t;

permute(inblock,iperm,iters[0]);
for (i=0; i<16; i++)
iter(15-i,iters[i],iters[i+1]);

s = swap; t = &iters[16][4];
*s++ = *t++; *s++ = *t++; *s++ = *t++; *s++ = *t++;
t = &iters[16][0];
*s++ = *t++; *s++ = *t++; *s++ = *t++; *s++ = *t++;
permute(swap,fperm,outblock);

return 0;
}

static int permute(char *inblock, char perm[16][16][8], char *outblock) /* 初始换位/最后换位变换*/
{
register int i,j;
register char *ib, *ob;
register char *p, *q;

for (i=0, ob = outblock; i<8; i++)
*ob++ = 0;
ib = inblock;
for (j = 0; j < 16; j += 2, ib++)
{
ob = outblock;
p = perm[j][(*ib >> 4) & 017]; /*高四位*/
q = perm[j + 1][*ib & 017]; /*低四位*/
for (i = 0; i < 8; i++)
*ob++ |= *p++ | *q++;
/*-----------------*(ob++)=(*ob)|(*(p++)|*(q++))-----------------*/
}

return 0;
}

static char 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 };

static char 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 };

static char pc1[] /* 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 };

static char totrot[] /* 密钥生成中的循环左移位的累计次数*/
= { 1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28 };

static char pc1m[56];
static char pcr[56];

static char pc2[] /* 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 };

static char si[8][64] /* 48->32 bit 压缩表*/
= { /* S[1] */
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,
/* S[2] */
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,
/* S[3] */
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,
/* S[4] */
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,
/* S[5] */
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,
/* S[6] */
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,
/* S[7] */
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,
/* S[8] */
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 };

static char p32i[] /* 32-bit 单纯换位表*/
= { 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 };

wyj1974 2004-10-25
  • 打赏
  • 举报
回复
我下载了上述的东东,但结果还是不一样哦
yinzhiw 2004-10-25
  • 打赏
  • 举报
回复
这里可以下载
http://www.ksaiy.com/ynen/sf.asp
GoldShield 2004-10-25
  • 打赏
  • 举报
回复
不懂^_^
princesd 2004-10-25
  • 打赏
  • 举报
回复
沉的有点厉害哦
ksaiy 2004-10-25
  • 打赏
  • 举报
回复
在你给的VC代码我没有看到生成密钥这步..
迭代顺序 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

你可以按照上面我给你的分析看一下我的代码。你就知道结果了。
wyj1974 2004-10-25
  • 打赏
  • 举报
回复
这些我都有呀!
ksaiy 2004-10-25
  • 打赏
  • 举报
回复
子密钥生成过程具体解释如下:
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

生成子密钥的代码:
procedure makeKey(inKey: array of Byte; var outKey: array of TKeyByte);
const
bitDisplace: array[0..15] of Byte =
( 1,1,2,2, 2,2,2,2, 1,2,2,2, 2,2,2,1 );
var
outData56: array[0..6] of Byte;
key28l: array[0..3] of Byte;
key28r: array[0..3] of Byte;
key56o: array[0..6] of Byte;
i: Integer;
begin
permutationChoose1(inKey, outData56);

key28l[0] := outData56[0] shr 4;
key28l[1] := (outData56[0] shl 4) or (outData56[1] shr 4);
key28l[2] := (outData56[1] shl 4) or (outData56[2] shr 4);
key28l[3] := (outData56[2] shl 4) or (outData56[3] shr 4);
key28r[0] := outData56[3] and $0f;
key28r[1] := outData56[4];
key28r[2] := outData56[5];
key28r[3] := outData56[6];

for i := 0 to 15 do
begin
cycleMove(key28l, bitDisplace[i]);
cycleMove(key28r, bitDisplace[i]);
key56o[0] := (key28l[0] shl 4) or (key28l[1] shr 4);
key56o[1] := (key28l[1] shl 4) or (key28l[2] shr 4);
key56o[2] := (key28l[2] shl 4) or (key28l[3] shr 4);
key56o[3] := (key28l[3] shl 4) or (key28r[0]);
key56o[4] := key28r[1];
key56o[5] := key28r[2];
key56o[6] := key28r[3];
permutationChoose2(key56o, outKey[i]);
end;
end;
ksaiy 2004-10-25
  • 打赏
  • 举报
回复
三.解密
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

ksaiy 2004-10-25
  • 打赏
  • 举报
回复
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算法加密原理讲完了。
二.子密钥的生成
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

加载更多回复(22)

16,742

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 语言基础/算法/系统设计
社区管理员
  • 语言基础/算法/系统设计社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧