c语言密码加密程序6,RC6加密解密算法实现(C语言)

这次是RC6加解密算法。RC6继承了RC5的优点,在加密过程中不需要查表,加上算法中的乘法运算可以用平方代替,所以该算法对内存要求极低,这使得RC6适合在单片机上实现。至于RC6的安全性,对RC6最为有效的攻击是强力攻击。但由于分组长度和密钥都至少是128bit,穷举法并不可行。对20轮的RC6,用线性分析法至少需要2^155个明文,用查分分析法至少需要2^238个明文。

RC6分组长度为128bit,使用了4个寄存器,并使用32bit的整数模乘运算,用于加强扩散特性。RC6更精确的表示是RC6-w/r/b,其中字长为w bit,r为加密轮数,b为加密密钥用字节表示的长度。通常令w=32,r=20,b=16(24,32)。

加密过程:(把128bit明文放入4个32bit的寄存器A、B、C、D中)

B=B+S[0] (S为密钥)

D=D+S[1]

for i=1 to r do

t=ROL(B*(2B+1),log2w)

u=ROL(D*(2D+1),log2w)

A=ROL(A⊕t,u)+S[2i]

C=ROL(C⊕u,t)+S[2i+1]

(A,B,C,D)=(B,C,D,A)

A=A+S[2r+2]

C=C+S[2r+3]

A、B、C、D即为密文。

解密过程:(把128bit密文放入4个32bit的寄存器A、B、C、D中)

C=C-S[2r+3]

A=A-S[2r+2]

for i=r down to 1 do

(A,B,C,D)=(D,A,B,C)

u=ROL(D*(2D+1),log2w)

t=ROL(B*(2B+1),log2w)

C=ROR(C-S[2i+1],t)⊕u

A=ROR(A-S[2i],u)⊕t

D=D-S[1]

B=B-S[0]

A、B、C、D即为明文。

密钥扩展方案:(在密钥扩展中用到两个常数P、Q,P=0xB7E15163,Q=0x9E3779B9。

首先,将用户密钥输入到c个w比特字的L[0],...,L[c-1]阵列,若不够,用0字节填充,其中c为8b/w的整数部分)

个人理解:每个L阵列可以存放4个字符,即若c为4时,密钥密钥最长为16个字符。

S[0]=P

for i=1 to 2r+3 do

S[i]=S[i-1]+Q

用户密钥混合到S中

A=B=i=j=0

v=3*max{c,2r+4}

for s=1 to v do循环体循环v次

A=S[i]=ROL(S[i]+A+B,3)

B=L[j]=ROL(L[j]+A+B,A+B)

i=(i+1)mod(2r+4)

j=(j+1)modc

输出S[0],S[1],...,S[2r+3]即为子密钥

个人心得:1、将需要处理的数据统一当做十六进制运算,输入字符的asc码可以通过位移运算处理成十六进制

2、int型和unsigned int最高都可以存放0xffffffff,但前者的第一位(二进制)表示正负,后者才是真正的0xffffffff

3、<>表示左移和右移(二进制,十进制的话相当于乘上2的n次方),是不循环的!左移末尾补0,右移前端补1!

(这些都是这次编程中困扰过我的问题,对这些概念不清楚或者解密逆不回去的童鞋也请留意一下哦~)

下面贴一波代码

#include

#include

#include

const unsigned int r=20;

const unsigned int w=32;

const unsigned int b=16;

const unsigned int c=4;

const unsigned int p=0xb7e15163;

const unsigned int q=0x9e3779b9;

unsigned int moveleft(unsigned int x,unsigned int y);

unsigned int moveright(unsigned int x,unsigned int y);

void keyextend(unsigned int *s,unsigned int *l);

void encryp(unsigned int *A,unsigned int *B,unsigned int *C,unsigned int *D,unsigned int *S);

void decryp(unsigned int *A,unsigned int *B,unsigned int *C,unsigned int *D,unsigned int *S);

unsigned int moveleft(unsigned int x,unsigned int y)

{

unsigned int i,temp;

if(y/32!=0)

y=y%32;

for (i=0; i

{

temp=x&0x80000000;

x=x<<1;

x=x+((temp>>31)&0x00000001);

}

return x;

}

unsigned int moveright(unsigned int x,unsigned int y)

{

unsigned int i,temp;

if(y/32!=0)

y=y%32;

for (i=0; i

{

temp=x&0x00000001;

x=x>>1;

x=(x&0x7fffffff)+(temp<<31);

}

return x;

}

void keyextend(unsigned int *s,unsigned int *l)

{

unsigned int i,j,k,a,b;

s[0]=p;

for (i=1; i<=43; i++)

s[i]=s[i-1]+q;

a=0;

b=0;

i=0;

j=0;

for (k=1; k<=132; k++)

{

s[i]=s[i]+a+b;

s[i]=moveleft(s[i],3);

a=s[i];

l[j]=l[j]+a+b;

l[j]=moveleft(l[j],(a+b));

b=l[j];

i=(i+1)%44;

j=(j+1)%4;

}

}

void encryp(unsigned int *A,unsigned int *B,unsigned int *C,unsigned int *D,unsigned int *S)

{

int i,j,t,u,temp;

*B=*B+S[0];

*D=*D+S[1];

j=(unsigned int)(log(w)/log(2));

for (i=1; i<=r; i++)

{

t=moveleft(((*B)*(2*(*B)+1)),j);

u=moveleft(((*D)*(2*(*D)+1)),j);

temp=moveleft(((*A)^t),u);

*A=temp+S[2*i];

temp=moveleft(((*C)^u), t);

*C=temp+S[2*i+1];

temp=*A;

*A=*B;

*B=*C;

*C=*D;

*D=temp;

}

*A=*A+S[2*r+2];

*C=*C+S[2*r+3];

}

void decryp(unsigned int *A,unsigned int *B,unsigned int *C,unsigned int *D,unsigned int *S)

{

unsigned int i,j,u,t,temp;

j=(unsigned int)(log(w)/log(2));

*C=*C-S[2*r+3];

*A=*A-S[2*r+2];

for (i=r; i>=1; i--)

{

temp=*D;

*D=*C;

*C=*B;

*B=*A;

*A=temp;

u=moveleft(((*D)*(2*(*D)+1)),j);

t=moveleft(((*B)*(2*(*B)+1)),j);

temp=moveright(((*C)-S[2*i+1]),t);

*C=temp^u;

temp=moveright(((*A)-S[2*i]), u);

*A=temp^t;

}

*D=*D-S[1];

*B=*B-S[0];

}

int main()

{

int ch;

unsigned int A,B,C,D,S[2*r+4],L[c]={0};

char plaintxt[16]={0},key[c*4],ciphertxt[16]; //plaintxt接收明文,key接收用户密钥,cipertxt存放解密后明文

unsigned int i,j,temp,keylong;

char g;

printf("请输入选择:1.文件读写(从a.txt里读出明文,把密文写入b.txt,解密后写入c.txt) 2.键盘读入文件 \n");

scanf("%d",&ch);

getchar();//缓冲回车符

if(ch==1)

{

FILE *fp1;

fp1=fopen("/Users/air/Documents/a.txt","r");

if (!fp1) {

printf("wrong1");

return 0;

}

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

{

g=fgetc(fp1);

if (g==' ')

g=fgetc(fp1);

else if(g=='\n'||g==EOF)

{

break;

}

plaintxt[i]=g;

}

fclose(fp1);

}

else

{

printf("请输入明文\n");

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

{

g=getchar();

if (g==' ')

g=getchar();

else if(g=='\n')

break;

plaintxt[i]=g;

}

if(i==16)

getchar(); //缓冲回车符

}

printf("请输入密钥\n");

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

{

g=getchar();

if (g==' ') {

g=getchar();

}

else if (g=='\n')

break;

key[i]=g;

}

keylong=i;

j=0;

for (i=0; i

{

temp=(unsigned int)key[i];

if(i%4==3)

temp=temp<<24;

else if(i%4==2)

temp=temp<<16;

else if(i%4==1)

temp=temp<<8;

L[j]=L[j]+temp;

if (i%4==3)

j++;

}

/*明文处理成十六进制*/

A=((unsigned int)plaintxt[0]<<24)+((unsigned int)plaintxt[1]<<16)+((unsigned int)plaintxt[2]<<8)+(unsigned int)plaintxt[3];

B=((unsigned int)plaintxt[4]<<24)+((unsigned int)plaintxt[5]<<16)+((unsigned int)plaintxt[6]<<8)+(unsigned int)plaintxt[7];

C=((unsigned int)plaintxt[8]<<24)+((unsigned int)plaintxt[9]<<16)+((unsigned int)plaintxt[10]<<8)+(unsigned int)plaintxt[11];

D=((unsigned int)plaintxt[12]<<24)+((unsigned int)plaintxt[13]<<16)+((unsigned int)plaintxt[14]<<8)+(unsigned int)plaintxt[15];

keyextend(S,L);

encryp(&A,&B,&C,&D,S);

if(ch==1)

{

FILE *fp2;

fp2=fopen("/Users/air/Documents/b.txt", "w");

if(!fp2)

{

printf("wrong2");

return 0;

}

fprintf(fp2,"%x %x %x %x\n",A,B,C,D);

fclose(fp2);

}

else

{

printf("密文(A,B,C,D):\n");

printf("%x %x %x %x\n",A,B,C,D);

}

decryp(&A,&B,&C,&D,S);

/*十六进制还原成明文*/

ciphertxt[0]=((A&0xff000000)>>24)&0xff;

ciphertxt[1]=((A&0xff0000)>>16)&0xff;

ciphertxt[2]=((A&0xff00)>>8)&0xff;

ciphertxt[3]=A&0xff;

ciphertxt[4]=((B&0xff000000)>>24)&0xff;

ciphertxt[5]=((B&0xff0000)>>16)&0xff;

ciphertxt[6]=((B&0xff00)>>8)&0xff;

ciphertxt[7]=B&0xff;

ciphertxt[8]=((C&0xff000000)>>24)&0xff;

ciphertxt[9]=((C&0xff0000)>>16)&0xff;

ciphertxt[10]=((C&0xff00)>>8)&0xff;

ciphertxt[11]=C&0xff;

ciphertxt[12]=((D&0xff000000)>>24)&0xff;

ciphertxt[13]=((D&0xff0000)>>16)&0xff;

ciphertxt[14]=((D&0xff00)>>8)&0xff;

ciphertxt[15]=D&0xff;

if(ch==1)

{

FILE *fp3;

fp3=fopen("/Users/air/Documents/c.txt", "w");

if(!fp3)

{

printf("wrong3");

return 0;

}

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

{

if(ciphertxt[i]==0)

break;

fprintf(fp3,"%c",ciphertxt[i]);

}

fclose(fp3);

}

else

{

printf("解密后:\n");

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

{

if(ciphertxt[i]==0)

{

printf("\n");

break;

}

printf("%c",ciphertxt[i]);

}

}

return 0;

}

运行截图:

0818b9ca8b590ca3270a3433284dd417.png

a.txt

0818b9ca8b590ca3270a3433284dd417.png

b.txt

0818b9ca8b590ca3270a3433284dd417.png

c.txt

0818b9ca8b590ca3270a3433284dd417.png

键盘读入明文加解密

0818b9ca8b590ca3270a3433284dd417.png

注:1、明文接收时我把空格处理掉了,如果需要空格请自行改相关部分

0818b9ca8b590ca3270a3433284dd417.png

2、明文和密文可以不足需要的长度,但如果超过也没影响,反正没接收。。

3、这篇代码是在Xcode上写的,搬到其他编译器可能会出现水土不服,比如初始化数组长度时会报错,把const那部分改成define或者写死数据应该就能解决了,吧。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值