admin 管理员组

文章数量: 887021


2023年12月22日发(作者:javaweb管理系统)

恺撒密码的加密程序

恺撒密码是公元前50年古罗马恺撒用过的密码,罗马的军队用凯撒密码(三个字母表轮换)进行通信,加密方法是把a变成D,b变成E,c换成F,依次类推,z换成C。

将替换密码用于军事用途的第一个文件记载是恺撒著的《高卢记》。恺撒描述了他如何将密信送到正处在被围困、濒临投降的西塞罗。其中罗马字母被替换成希腊字母使得敌人根本无法看懂信息。

苏托尼厄斯在公元二世纪写的《恺撒传》中对恺撒用过的其中一种替换密码作了详细的描写。恺撒只是简单地把信息中的每一个字母用字母表中的该字母后的第三个字母代替。这种密码替换通常叫做恺撒移位密码,或简单的说,恺撒密码。

尽管苏托尼厄斯仅提到三个位置的恺撒移位,但显然从1到25个位置的移位我们都可以使用, 因此,为了使密码有更高的安全性,单字母替换密码就出现了。

如:

明码表 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

密码表 Q W E R T Y U I O P A S D F G H J K L Z X C V B N M

明文 F O R E S T

密文 Y G K T L Z

只需重排密码表二十六个字母的顺序,允许密码表是明码表的任意一种重排,密钥就会增加到四千亿亿亿多种,我们就有超过4×1027种密码表。破解就变得很困难。

用C语言编写恺撒密码的加密解密程序,要求:

每个字符替换为其在ASCII码中前29个字符的符号。例如,输入k,输出为N。

加密:

方法一:

#include

main()

{

char str[100];

int i=0;

gets(str);

while (str!='0')

{

printf("%c",str-29);

i++;

}

}

方法二:

#include

main()

{

char c;

while((c=getchar())!='n')

{

if((c>='a'&&c<='z') || (c>='A'&&c<='Z'))

{

c=c+4;

if(c>'Z'&&c<'Z'+4 || c>'z') c=c-26;

}

printf("%c",c);

}

}

程序三:

#include

main()

{ char i;

printf("Input your word:");

while(1)

{ i=getchar();

if(i!='n')

printf("%c",i-29);

else break;

}

}

简述密码学

密码学历和密码系统种类

密码学(Cryptology)一字源自希腊文"krypto's"及"logos"两字,直译即为"隐藏"及"讯息"之意。

密码学的起源可能要追溯到人类刚刚出现,并且尝试去学习如何通信的时候。他们不得不去寻找方法确保他们的通信的机密。但是最先有意识的使用一些技术的方法来加密信息的可能是公元六年前的古希腊人。他们使用的是一根叫scytale的棍子。送信人先绕棍子卷一张纸条,然后把要写的信息打纵写在上面,接着打开纸送给收信人。如果不知道棍子的宽度(这里作为密匙)是不可能解密里面的内容的。

后来,罗马的军队用凯撒密码(三个字母表轮换)进行通信。恺撒密码是公元前50年古罗马恺撒用过的密码,加密方法是把a变成D,b变成E,c换成F,依次类推,z换成C。这样明文和密文的字母就建立一一对应的关系。

在随后的19个世纪里面,主要是发明一些更加高明的加密技术,这些技术的安全性通常依赖于用户赋予它们多大的信任程度。在19世纪Kerchoffs写下了现代密码学的原理。其中一个的原理提到:加密体系的安全性并不依赖于加密的方法本身,而是依赖于所使用的密匙。.

在二次大战中,密码更是扮演一个举足轻重的角色,许多人认为同盟国之所以能打赢这场战争完全归功于二次大战时所发明的破译密文数字式计算器破解德日密码。破译密文数字式计算器又名图灵机,是数学家图灵所发明的。公元1949年,Shannon提出第一篇讨论密码系统通讯理论之论文,近代密码学可说是滥觞于斯。直至公元1975年,Diffie与Hellman提出公开金匙密码系统之观念,近代密码学之研究方向,正式脱离秘密金匙密码系统之窠臼,蓬勃发展,至今已近二十年。发展至今,已有二大类的密码系统。第一类为对称金钥(Symmetric Key),第二类为非对称金钥(Public Key)。

密码法的基本原理

可以分成两种:移位法(transposition)和替代法(substitution)。

移位法就是将讯息里面的文字,根据一定的规则改变顺序,这种方法,在文字数量很大的时候,便可以显示出他的优势,例如"Hello World"才不过10个字母便可以有11780000种排列的方式。另外一种方法,就是替代法,还可以分成两种,一种是单字替代,一种是字母替代,两种的原理是一样的,就是利用文字相对顺序的对应,来改变原来的文章,以英文为例,我们可以把英文字母往后移动三个位置,即:

a b c d e f g h i j k l m n o p q r s t u v w x y z

D E F G H I J K L M N O P Q R S T U V W X Y Z A B C

泛例: Hello World How are you

khoor zruog krz duh brx

这句话就变的难以辨认了,而且如果发信人收信人有协议好的话,那还可以把文字之间的空白删除,反正翻译回来的时候,可以靠文句的意思,来推测断句断字的时机。 而单字替代,则是以每个单字,都去换成另外一个相对应的单字,这样来改写原文,变成一个无法辨认其意义的加密文件。

移位法当然不只限于一种,光是英文字母不考虑大小写,就可以有25种互异的方法,每种密码法,都可视为一种加密法,我们称为算法(algorithm),和一把钥匙(KEY)的组合结果。钥匙是用来指定加密程序的演算细节。以移位法为例,算法是只以密码字母集里的字母,取代明文字母集里面的字母,钥匙便是收发信人定义的密码字母集。

密码学术语

明文用M(Message,消息)或P(Plaintext,明文)表示,它可能是比特流、文本文件、位图、数字化的语音流或者数字化的视频图像等。

密文用C(Cipher)表示,也是二进制数据,有时和M一样大,有时稍大。通过压缩和加密的结合,C有可能比P小些。

加密函数E作用于M得到密文C,用数学公式表示为:E(M)=C。解密函数D作用于C产生M,用数据公式表示为:D(C)=M。先加密后再解密消息,原始的明文将恢复出来,D(E(M))=M必须成立。

对称金钥(Symmetric Key)。经典对称加密——DES。

举一个简单的对称的钥匙密码学的范例, 假想从朋友处收到一个通知. 你和你的朋友同意来加解密你们的讯息,你们将使用下列算法: 每个字母将会上移三个字母, 例如 A=C,

B=D, 而 Y 和 Z 转一圈回到 A和 B,这个方程式 ("每个字母上移三个字母") 就是送信者使用来加密讯息的钥匙; 而收信者使用相同的钥匙来解密 .

任何人如果没有钥匙就不能够读此讯息. 因为相同的钥匙视同实用来加密及解密讯息, 这个方法是一个 对称钥匙的算法. 这类的密码学及是我们所知的秘密钥匙密码学,因为此钥匙 必须被秘密保存于送信者和收信者,以保护资料的完整性.

DES(Data Encryption Standard)算法,于1977年得到美国政府的正式许可,是一种用56位密钥来加密64位数据的方法。

DES算法的入口参数有三个:Key、Data、Mode。其中Key为8个字节共64位,是DES算法的工作密钥;Data也为8个字节64位,是要被加密或被解密的数据;Mode为DES的工作方式有两种:加密或解密。

DES算法是这样工作的:如Mode为加密,则用Key去把数据Data进行加密,生成Data的密码形式(64位)作为DES的输出结果;如Mode为解密,则用Key去把密码形式的数据Data解密,还原为Data的明码形式(64位)作为DES的输出结果。

DES算法实现加密需要三个步骤:

第一步:变换明文。对给定的64位比特的明文x,首先通过一个置换IP表来重新排列x,从而构造出64位比特的x0,x0=IP(x)=L0R0,其中L0表示x0的前32比特,R0表示x0的后32位。

第二步:按照规则迭代。规则为

Li = Ri-1

Ri = Li?f(Ri-1,Ki)

第三步:经过i次迭代运算后。得到Li、Ri,将此作为输入,进行逆置换,即得到密文输出。

DES算法具有比较高安全性,到目前为止,除了用穷举搜索法对DES算法进行攻击外,还没有发现更有效的办法。而56位长的密钥的穷举空间为256,这意味着如果一台计算机的速度是每一秒种检测一百万个密钥,则它搜索完全部密钥就需要将近2285年的时间,可见,这是难以实现的,当然,随着科学技术的发展,当出现超高速计算机后,我们可考虑把DES密钥的长度再增长一些,以此来达到更高的保密程度。

非对称金钥(Public Key)。经典非对称加密——RSA。

非对称性或公开的钥匙 密码学, 不同于对称性的 密码学, 在于其加密钥匙只适用于单一使用者.

钥匙被分为两个部分:

一把私有的钥匙, 仅有使用者才拥有.

一把公开的钥匙, 可公开发行配送,只要有要求即取得.

每支钥匙产生一个被使用来改变内文的功能. 私有的钥匙 产生一个 私有改变内文的功能,而公开的钥匙 产生一个 公开改变内文的功能.

这些功能是反向相关的, 例如., 如果一个功能是用来加密讯息,另外一个功能则被用来解密讯息.不论此改变内文功能的次序为何皆不重要.

公开的钥匙系统的优势是两个使用者能够安全的沟通而不需交换秘密钥匙. 例如, 假设一个送信者需要传送一个信息给一个收信者, 而信息的秘密性是必要的, 送信者以收信者的公开的钥匙来加密,而仅有收信者的私有的钥匙能够对此信息解密.

公开的钥匙密码学是非常适合于提供认证,完整和不能否认的服务, 所有的这些服务及是我们所知的数字签名。

1965年,美国史丹福大学电机工程系--默克尔、迪菲、赫尔曼等三人研究密码学可惜并未有所发现。另外在英国通讯电子保安组(CESG)秘密机构的切尔纳姆发现了还原密码式,但是由于属于秘密机构,所以不能公开。1976年,Diffie和Hellman在文章“密码学新方向(New Direction in Cryptography)”中首次提出了公开密钥密码体制的思想,1977年,Rivest、Shamir和Adleman三个人实现了公开密钥密码体制,现在称为RSA公开密钥体制,它是第一个既能用于数据加密也能用于数字签名的算法。这种算法易于理解和操作,算法的名字以发明者的名字命名:Ron Rivest, Adi Shamir和Leonard Adleman。他们成立RSA SecurityCompany 现时值25亿美元,在传送信用卡时起了很大作用。RSA已安装了5亿套产品在IE , Netscape下的小锁就是RSA的产品。数学挂锁第一个发现不是美国,但是第一个公开。数学挂锁上锁易,还原难,所以受广泛使用,亦即是信息编码保密。

数学挂锁泛例:

数学挂锁用单向式:N=pxq <--例子 N(合成数)=两个质数的乘

11x17=187=N

还原单向式公式:C=Me(mod N) *e是M的次数。

M*13*(mod 187)=C *13是M的次数*

c=165

x=88 (password kiss)

88*13*(mod 187)=165 *13是88的次数*

modN=M

C*1/e*mod(p-1)(q-1)=88

C=165

p=11

q=17

answer:mod 187=88

RSA的安全性依赖于大数分解,但是否等同于大数分解一直未能得到理论上的证明,因为没有证明破解 RSA就一定需要作大数分解。假设存在一种无须分解大数的算法,那它肯定可以修改成为大数分解算法。目前, RSA 的一些变种算法已被证明等价于大数分解。不管怎样,分解n是最显然的攻击方法。现在,人们已能分解多个十进制位的大素数。因此,模数n必须选大一些,因具体适用情况而定

虽然RSA的安全性一直未能得到理论上的证明。它经历了各种攻击,至今未被完全攻破。

整个密码学发展的程序,辨识找寻新的算法,和保护钥匙避免被解密者发现的程序,钥匙在密码学中非常重要,因为即使算法相同或太简单,没有加密的钥匙的话,我们仍然很难去破解加密的文件。

#include

#include

char encrypt(char ch,int n)/*加密函数,把字符向右循环移位n*/

{

while(ch>='A'&&ch<='Z')

{

return ('A'+(ch-'A'+n)%26);

}

while(ch>='a'&&ch<='z')

{

return ('a'+(ch-'a'+n)%26);

}

return ch;

}

void menu()/*菜单,1.加密,2.解密,3.暴力破解,密码只能是数字*/

{

clrscr();

printf("n===============================================================================");

printf("t the file");

printf("t the file");

printf(" decrypt file");

printf("");

printf("===============================================================================n");

printf("Please select a item:");

return;

}

void logo()/*显示版权信息*/

{

printf("nguifanglin Encryption [Version:1.0.0]");

printf("nCopyright (C) 2004 guifanglinsoft Corp.n");

printf("");

return;

}

main()

{

int i,n;

char ch0,ch1;

FILE *in,*out;

char infile[20],outfile[20];

textbackground(BLACK);

textcolor(LIGHTGREEN);

clrscr();

logo();

sleep(3);/*等待3秒*/

menu();

ch0=getch();

while(ch0!='4')

{

if(ch0=='1')

{

clrscr();

printf("nPlease input the infile:");

scanf("%s",infile);/*输入需要加密的文件名*/

if((in=fopen(infile,"r"))==NULL)

{

printf("Can not open the infile!n");

printf("Press any key to exit!n");

getch();

exit(0);

}

printf("Please input the key:");

scanf("%d",&n);/*输入加密密码*/

printf("Please input the outfile:");

scanf("%s",outfile);/*输入加密后文件的文件名*/

if((out=fopen(outfile,"w"))==NULL)

{

printf("Can not open the outfile!n");

printf("Press any key to exit!n");

fclose(in);

getch();

exit(0);

}

while(!feof(in))/*加密*/

{

fputc(encrypt(fgetc(in),n),out);

}

printf("nEncrypt is over!n");

fclose(in);

fclose(out);

sleep(1);

}

if(ch0=='2')

{

clrscr();

printf("nPlease input the infile:");

scanf("%s",infile);/*输入需要解密的文件名*/

if((in=fopen(infile,"r"))==NULL)

{

printf("Can not open the infile!n");

printf("Press any key to exit!n");

getch();

exit(0);

}

printf("Please input the key:");

scanf("%d",&n);/*输入解密密码(可以为加密时候的密码)*/

n=26-n;

printf("Please input the outfile:");

scanf("%s",outfile);/*输入解密后文件的文件名*/

if((out=fopen(outfile,"w"))==NULL)

{

printf("Can not open the outfile!n");

printf("Press any key to exit!n");

fclose(in);

getch();

exit(0);

}

while(!feof(in))

{

fputc(encrypt(fgetc(in),n),out);

}

printf("nDecrypt is over!n");

fclose(in);

fclose(out);

sleep(1);

}

if(ch0=='3')

{

clrscr();

printf("nPlease input the infile:");

scanf("%s",infile);/*输入需要解密的文件名*/

if((in=fopen(infile,"r"))==NULL)

{

printf("Can not open the infile!n");

printf("Press any key to exit!n");

getch();

exit(0);

}

printf("Please input the outfile:");

scanf("%s",outfile);/*输入解密后文件的文件名*/

if((out=fopen(outfile,"w"))==NULL)

{

printf("Can not open the outfile!n");

printf("Press any key to exit!n");

fclose(in);

getch();

exit(0);

}

for(i=1;i<=25;i++)/*暴力破解过程,在察看信息正确后,可以按'Q'或者'q'退出*/

{

rewind(in);

rewind(out);

clrscr();

printf("===============================================================================n");

printf("The outfile is:n");

printf("===============================================================================n");

while(!feof(in))

{

ch1=encrypt(fgetc(in),26-i);

putch(ch1);

fputc(ch1,out);

}

printf("n===============================================================================n");

printf("The current key is: %d n",i);/*显示当前破解所用密码*/

printf("Press 'Q' to quit and other key ");

printf("===============================================================================n");

ch1=getch();

if(ch1=='q'||ch1=='Q')/*按'Q'或者'q'时退出*/

{

clrscr();

logo();

printf("nGood Bye!n");

fclose(in);

fclose(out);

sleep(3);

exit(0);

}

}

printf("nForce decrypt is over!n");

fclose(in);

fclose(out);

sleep(1);

}

menu();

ch0=getch();

}

clrscr();

logo();

printf("nGood Bye!n");

sleep(3);

getch();

}

恺撒密码是一种简单的信息加密方法,通过将信息中每个字母在字母表中向后移动常量k来实现加密。要解密信息,则将每个字母向前移动相同数目的字符即可。如k=3,对已加密的信息frpsxwhu vbvwhpv,将解密为computer systems.

设要加密的信息为一个串,组成串的字符均取自ASC||中的小写英文字母,假使串采用顺序存储,串的长度存放在数组的0号单元,串值从1号单元开始存放。下面给出具体的加密算法。

Void kaisa(char s[],cha t[],int k)

{

T[0]=s[0];

For(i=1;i<=s[0];i++)

T=(s-97+k)%26;


本文标签: 加密 密码 钥匙 算法 字母