古典密码学.docx
- 文档编号:8373900
- 上传时间:2023-01-30
- 格式:DOCX
- 页数:20
- 大小:287.41KB
古典密码学.docx
《古典密码学.docx》由会员分享,可在线阅读,更多相关《古典密码学.docx(20页珍藏版)》请在冰豆网上搜索。
古典密码学
现代密码学与加解密技术实验报告
实验名称
Vigenere和Columnpermutationcipher的编程实现
班级
学号
姓名
日期
成绩
评阅人
软件学院
一、实验目的与意义
实验目的:
通过编程实现Vigenerecipher和Columnpermutationcipher的加、解密算法,加深对古典密码体制的了解,为深入学习密码学奠定基础。
实验意义:
通过本次实验验证学习过的理论知识,更进一步的了解替代密码的加密过成功,更重要的是通过实验加强实验手段与实践技能,培养分析问题、解决问题、应用知识的能力和创新精神,全面提高综合素质
二、实验环境
操作系统:
Windows7
调试软件名称及版本号:
VC++6.0
上机地点:
综合楼311
三、实验的预习内容
1、Vigenercipher
实验前预习主要内容:
(1)预习有关Vigenerecipher加密和解密的原理。
(2)预习二维数组的操作,利用二维数组将表显示出来。
(3)找到将关键字重复写在明文上的过程。
实验思路:
(1)加密过程为输入明文和密钥,将明文和密钥的长度进行比较,根据情况将密钥进行扩展,之后按照Vieneretable进行查表找到相对应的密文。
(2)解密过程和加密过程的原来基本相同,在这不进行赘述。
程序框图:
加/解密
Y
2、Columnpermutationcipher
实验前预习内容:
(1)预习有关Columnpermutationcipher加密和解密的原理。
(2)掌握二维数组的操作,利用二维数组将明文存放在矩阵当中。
(3)掌握排序算法,将密钥字母进行排序找到输出列的顺序。
实验思路:
(1)加密过程,将明文和密钥输入,将明文放入到矩阵当中,并且计算是否需要添加无效字符‘q’。
之后利用冒泡排序将密钥字符进行排序,得到读取列的顺序,进而将密文输出。
(2)解密过程,将密文和密钥输入,将密文排序以便恢复明文矩阵,之后进行列读取将明文矩阵恢复。
该过程和加密过程相似。
程序框图:
加/解密
四、实验的步骤与调试方法
1、Vigenerecipher
实验步骤:
(1)建立win32consoleapplication工作空间。
(2)建立源文件。
(3)构建Vigenere表。
for(i=0;i<26;i++)
{
for(j=0;j<26;j++)
{
table[i][j]=a[(j+i)%26];
}
}
(4)根据密钥和明文的长度情况扩展密钥。
if(key_len { for(i=key_len;i { key[i]=key[(i%key_len)]; } } (5)根据密钥和明文的对应情况,查表得到结果。 for(i=0;i<26;i++) { for(j=0;j<26;j++) { table[i][j]=a[(j+i)%26]; } } (6)解密过程和加密过程相似,只是在查表的时候为逆查表。 for(i=0;i { //在表中进行逆查表找到明文字母 for(j=0;j<26;j++) { if(table[(key[i]-97)][j]==str[i]) printf("%c",table[0][j]); } } (7)进行编译、链接、执行,按照提示输入密钥和明文(密文)。 遇到的问题和调试方法: (1)在实验进行加密操作显示Vigeneretable时,总是出错,经过检查发现我忽略了在字母表移位过程后需要进行一次模操作,经过修改,Vigenertable正常显示。 2、Columnpermutationcipher 实验步骤: (1)建立win32consoleapplication工作空间。 (2)建立源文件。 (3)确定矩阵的形状以及是否需要填充无效字符。 //计算矩阵的行数以及是否需要填充无效字符 t3=str_len%key_len;//多出来的字符 if(t3==0) { line=str_len/key_len;//明文矩阵的行数 add=0;//需要填充的无效字符的个数 } else { line=str_len/key_len+1;//明文矩阵的行数 add=key_len-t3;//需要填充的无效字符的个数 } (4)处理密钥,得到列读取顺序。 for(i=0;i { num[i]=0; for(j=0;j { if(key[j]<=key[i]) { num[i]=num[i]+1; } if(key[j]==key[i]&&j>i)//字符相同的情况 num[i]=num[i]-1; } } (5)将明文填充到矩阵当中,如果需要补充无效字符。 if(add! =0) { for(i=0;i { str[str_len+i]='q'; } } for(i=0;i { for(j=0;j { a[i][j]=str[i*key_len+j]; } } (6)之后按照列的顺序读取密文。 (7)解密过程和加密过程相似,只是恢复明文矩阵时为按列恢复。 for(i=0;i { for(j=0;j { a[j][num[i]-1]=str[i*line+j]; } } (8)进行编译、链接、执行,按照提示输入密钥和明文(密文)。 遇到的问题和调试方法: (1)在开始确定明文是否需要补充无效字符时,发现无法在矩阵最后加入无效字符,执行时发现程序中间便终止,无法正常进行,最后发现在补充无效字符时出现逻辑错误,将无效字符添加到了矩阵外,因而出现了错误,最后我将无效字符直接添加到了明文中,这样便可以直接将其填入明文矩阵。 五、实验数据与实验结果 1、Vigenerecipher 程序开始的界面,如果加密则选择1,如果要进行解密操作选择2。 之后进行加密操作,密钥为cipher,明文为vigenerecipher。 进行解密过程,密钥为cipher,密文为xqvlrvtmrptygz(上文密文)。 经过上述过程,发现结果相同,因此,实验过程正确。 2、Columnpermutationcipher 程序开始的界面,如果加密则选择1,如果要进行解密操作选择2。 之后进行加密操作,密钥为cipher,明文为columnpermutation,得到的密文为cpaumomunlrioetntq 进行解密,密钥为cipher,密文为cpaumomunlrioetntq(上文密文)。 经过上述过程,发现结果相同,因此,实验过程正确。 六、实验用程序清单(要有注释) 1、Vigenerecipher #include #include #include voidencryption() { inti,j; charkey[20];//密钥 charstr[100];//明文 intkey_len,str_len;//密钥长度 chartable[26][26];//表 chara[26]={'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'}; printf("请输入密钥: "); scanf("%s",&key); printf("请输入明文: "); scanf("%s",&str); key_len=strlen(key);//密钥长度 str_len=strlen(str);//明文长度 if(key_len { for(i=key_len;i { key[i]=key[(i%key_len)]; } printf("扩展密钥为: "); for(i=0;i { printf("%c",key[i]); } } for(i=0;i<26;i++) { for(j=0;j<26;j++) { table[i][j]=a[(j+i)%26]; } } /*printf("\n显示表: \n"); for(i=0;i<26;i++) { for(j=0;j<26;j++) { printf("%c",table[i][j]); } printf("\n"); }*/ printf("\n密文: "); for(i=0;i { printf("%c",table[(str[i]-97)][(key[i]-97)]); } printf("\n"); } voiddecryption() { inti,j; intkey_len,str_len;//密钥长度,密文长度 charkey[20];//密钥 charstr[100];//密文 chartable[26][26];//表 chara[26]={'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'}; printf("请输入密钥: "); scanf("%s",&key); printf("请输入密文: "); scanf("%s",&str); key_len=strlen(key);//密钥长度 str_len=strlen(str);//密文长度 if(key_len { for(i=key_len;i { key[i]=key[(i%key_len)]; } printf("扩展密钥为: "); for(i=0;i { printf("%c",key[i]); } } for(i=0;i<26;i++) { for(j=0;j<26;j++) { table[i][j]=a[(j+i)%26]; } } printf("\n明文: "); for(i=0;i { //在表中进行逆查表找到明文字母 for(j=0;j<26;j++) { if(table[(key[i]-97)][j]==str[i]) printf("%c",table[0][j]); } } printf("\n"); } voidmenu() { printf("********************VigenereCipher加解密过程********************\n"); printf("1.加密\n"); printf("2.解密\n"); } voidmain() { inti; menu(); printf("请选择你要进行的操作: \n"); scanf("%d",&i); if(i==1) { system("cls"); encryption(); } else { system("cls"); decryption(); } } 2、Columnpermutationcipher #include #include #include //加密过程 voidencryption() { charkey[20];//密钥 charstr[100];//明文 intnum[20];//确定密文读取列数的顺序 chara[20][20];//保存明文的矩阵 intkey_len,str_len;///密钥和明文的长度 intline,t3,add;//填充的行数和需要补充的无效字符的个数 inti=0,j=0; printf("请输入密钥: "); scanf("%s",&key); printf("请输入明文: "); scanf("%s",&str); key_len=strlen(key);//密钥长度 str_len=strlen(str);//明文长度 //计算矩阵的行数以及是否需要填充无效字符 t3=str_len%key_len;//多出来的字符 if(t3==0) { line=str_len/key_len;//明文矩阵的行数 add=0;//需要填充的无效字符的个数 } else { line=str_len/key_len+1;//明文矩阵的行数 add=key_len-t3;//需要填充的无效字符的个数 } //处理密钥,确定读取密文读取顺序 for(i=0;i { num[i]=0; for(j=0;j { if(key[j]<=key[i]) { num[i]=num[i]+1; } if(key[j]==key[i]&&j>i)//字符相同的情况 num[i]=num[i]-1; } } printf("密文列的读取顺序: "); for(i=0;i printf("%d",num[i]);//输出密钥结果 printf("\n"); //将明文填充到矩阵当中 //如果需要在矩阵中添加无效字符q if(add! =0) { for(i=0;i { str[str_len+i]='q'; } } for(i=0;i { for(j=0;j { a[i][j]=str[i*key_len+j]; } } printf("将明文装填到矩阵当中\n");//打印装填后的矩阵 for(i=0;i { for(j=0;j { printf("%c",a[i][j]); } printf("\n"); } printf("密文为: "); for(i=0;i { for(j=0;j { printf("%c",a[j][(num[i]-1)]); } } printf("\n"); } //解密过程 voiddecryption() { charkey[20];//密钥 charstr[100];//密文 intkey_len,str_len;///密钥和密文的长度 intnum[20];//确定读取列数的顺序 chara[20][20];//明文矩阵 intline;//行数 inti,j; printf("请输入密钥: "); scanf("%s",&key); printf("请输入密文: "); scanf("%s",&str); key_len=strlen(key);//密钥长度 str_len=strlen(str);//密文长度 line=str_len/key_len;//行数 //处理密钥,确定读取密文读取顺序,以便恢复明文矩阵 for(i=0;i { num[i]=0; for(j=0;j { if(key[j]<=key[i]) { num[i]=num[i]+1; } if(key[j]==key[i]&&j>i)//字符相同的情况 num[i]=num[i]-1; } } printf("密文列的读取顺序: "); for(i=0;i printf("%d",num[i]);//输出密钥结果 printf("\n"); //恢复明文矩阵 for(i=0;i { for(j=0;j { a[j][num[i]-1]=str[i*line+j]; } } printf("明文为"); for(i=0;i { for(j=0;j { printf("%c",a[i][j]); } } printf("\n"); } voidmenu() { printf("********************列置换密码加解密********************\n"); printf("1.加密\n"); printf("2.解密\n"); } voidmain() { inti; menu(); printf("请选择你要进行的操作: \n"); scanf("%d",&i); if(i==1) { system("cls"); encryption(); } else { system("cls"); decryption(); } } 七、思考题(必需回答)写明如下问题 1、Vigenere密码的原理是什么? 答: 原理是多表替代。 2、Vigenere密码的主要缺陷有哪些? 答: 主要缺陷是密钥的重复书写和密钥短。 3、对Vigenere密码的分析方法有哪几种? 答: 分析方法主要是Kasiski测试法和重合指数法。 4、对Vigenere密码的改进方法是什么? 答: 对Vigenere密码的改进方法是Autokey密码。 5、Columnpermutationcipher的原理是什么? 答: 原理是置换。 6、给定关键字为“experiment”,加密矩阵将包括几列,以及列置换的次序是什么? 答: 加密矩阵有10列,列置换的顺序为第1,10,7,2,8,4,5,3,6,9列。 7、简述对Columnpermutationcipher的分析方法。 答: 首先通过密文字符的长度确定矩阵的形状,之后进行频率分析来还原列的顺序。 8、Columnpermutationcipher的安全性增强方法是什么? 答: 使用Double-Transposition密码。 八、结束语 通过本次试验我对Vigenere加密算法和Columnpermutation密码有了更加全面深入的认识,以前的学习只是停留在理论层面,而这次课程给了我实践的机会。 通过实验很好的把古典密码应用于现代密码加解密技术中。 在这个过程中我也学到了很多关于编程方面的知识,提高了自己的编程水平。 九、参考文献 1、RichardJ.Spillman: 《CLASSICAL AND CONTEMPORARY CRYPTOLOGY》,清华大学出版社,2005-7 实验成绩 考查内容 分数 得分 做好实验内容的预习,写出预习报告 10 了解实验题目的调试方法 10 按实验要求预先设计好程序 10 认真记录实验数据并分析实验结果 10 实验后按要求书写实验报告,记录实验用数据及运行结果 30 创新能力强,在实验中设计的程序有一定的通用性,算法优化 20 实验过程中,具有严谨的学习态度,认真、踏实、一丝不苟的科学作风 10
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 古典 密码学