版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、五邑大学本科生实验指导书密码学基础实验指导书课程名称:密码学基础课程编号:课程性质:专业选修课课程总学时:48实验总学时:8任课教师:高伟峰一、实验教学目的和基本要求密码学基础是计算科学与技术本科专业开设的一门专业选修课,本课程的主要目标是让学生学习和了解密码学的一些基本概念,理解和掌握一些常用密码算法,包括加密和解密、认证理论及算法、安全计算原理及算法,学会进行效率分析和安全性分析。密码学是信息安全的核心技术,是实现安全通信的基础,所以实验和理论一样都很重要,实验能够让学生通过多个密码算法的程序设计实现,更好地掌握密码算法设计的机理和方法,熟悉网络攻击和防范方法。同时,基于密码系统设计的基本
2、方法和基本步骤,帮助学生理解密码学在信息安全中的地位,并引导了解密码学领域及信息安全领域的新进展、新方向。具体要求如下:1要求学生在上机前对本次实验的原理、内容、方案进行充分准备。2每次实验必须按要求的格式撰写实验报告,内容大体包括:实验目的、实验内容、实验及算法原理、程序清单、结果分析、总结。3实验成绩作为平时成绩的一部分。二、实验内容及学时分配 实验一 古典密码学实验(2学时)一、实验目的 通过实现简单的古典密码算法,理解密码学的相关概念如明文(plaintext)、密文(ciphertext)、加密密钥(encryption key)、解密密钥(decryption key)、加密算法(
3、encryption algorithm)、解密算法(decryption algorithm)等。二、实验内容 1)用cc+语言实现仿射变换(affine)加/解密算法;2)用cc+语言实现统计26个英文字母出现的频率的程序;3)利用仿射变换加/解密程序对一段较长的英文文章进行加密,再利用统计软件对明文和密文中字母出现的频率进行统计并作对比,观察有什么规律。 放射变换:加密:解密:其中a, b为密钥,且gcd(a, 26)=1实验要求:加/解密程序对任意满足条件的a、b都能够处理。三、实验步骤(1)统计26个英文字母出现的频率的程序#include<iostream>#inclu
4、de<fstream>#include<vector>using namespace std;void main() ifstream in("a.txt"); vector<int> s; vector<int> n(26,0); for(int i=0;i<26;+i) s.push_back(97+i); for(char x;in>>x; ) for(int i=0;i<26;+i) if(int(x)=si) ni+; float sum=0.0; for(int j=0;j<26;+j
5、) sum+=nj; cout<<"统计结果如下:"<<endl; for(int k=0;k<26;+k)/ nk=nk/sum; cout<<' '<<char(k+97)<<"出现的概率为:"<<nk/sum<<endl; /cout<<nk<<endl; (2)仿射变换加/解密程序对一段较长的英文文章进行加密#include <stdafx.h>#include<iostream>#includ
6、e<fstream>#include<vector>using namespace std;/判断两个数是不是互素(辗转相除)/bool gcd(int a)int f=26,g,r;g=a;dor=f%g;f=g;g=r;while(r);if(f=1)return 1;elsereturn 0;/求逆/int inv(int a)int x,i;for(i=1;i<=30;+i)if(26*i+1)%a=0)x=(26*i+1)/a;break;return x;/void main()cout<<"请你选择操作密码的方式:"&
7、lt;<endl<<" 0-表示加密 "<<endl<<" 1-表示解密 "<<endl;int z;cin>>z;if(z=0|z=1) /cout<<"请输入密钥a和b:"<<endl;int a,b;cin>>a>>b;if(a<1|a>25)|(b<0|b>25)cout<<"a,b的输入范围有错!"<<endl;elseif(gcd(a)=0)c
8、out<<"密钥a有误,与26不互素"<<endl;elseif(z=0)/加密算法 ifstream in("a.txt"); ofstream out("b.txt"); vector<int> s; for(char x;in>>x; ) s.push_back(int(x); for(int i=0;i<s.size();+i) si=(a*(si-97)+b)%26; out<<char(si+97); cout<<endl; cout<&l
9、t;"加密成功!明文请见"b.txt""<<endl; else/解密算法ifstream in("b.txt"); ofstream out("a.txt"); vector<int> s; for(char x;in>>x; ) s.push_back(int(x); for(int i=0;i<s.size();+i) si=inv(a)*(si-97-b+26)%26; out<<char(si+97);out<<endl;cout<&
10、lt;"解密成功!密文请见"a.txt""<<endl;/elsecout<<"所选操作无效!"<<endl;四、实验结果及分析该程序是对文件进行操作,结果如下:(1) 统计26个英文字母出现的频率的程序(2) 仿射变换加/解密程序对一段较长的英文文章进行加密下面是文本内容:实验二 aes密码的实现(4学时)一、实验目的 通过实现aes密码算法,理解对称密码机制。二、实验内容 1)在深入理解aes加密/解密算法理论的基础上,设计一个aes加密/解密软件系统;2)完成一个明文分组的加解密,明文和密钥是
11、十六进制,长度都为64比特(16个16进制数),输入明文和密钥,输出密文,进行加密后,能够进行正确的解密;3) 程序运行时,要求输出每一轮使用的密钥,以及每一轮加密或解密之后的16进制表示的值;4) 要求提供所设计系统的报告及完整的软件。三、实验步骤1.字节替换subbytes()变换是一个基于s盒的非线性置换,它用于将输入或中间态的每一个字节通过一个简单的查表操作,将其映射为另一个字节。映射方法是把输入字节的高四位作为s盒的行值,低四位作为列值,然后取出s盒中对应的行和列的元素作为输出。unsigned char subbytes(unsigned char state44) printf(
12、"after subbyte:n"); /取出中间态state映射到s盒中的值赋给中间态statefor(i=0;i<4;i+)for(j=0;j<4;j+)stateij=sboxstateij; for(i=0;i<4;i+) /输出到屏幕显示statefor(j=0;j<4;j+)printf("tt%02x ",stateij); printf("n");printf("n"); return 0; 2行移位shiftrows()完成基于行的循环移位操作,变换方法是第0行不动,第一行
13、循环左移一个字节,第二位循环左移两个字节,第三行循环左移三个字节。unsigned char shiftrows(unsigned char state44) printf("after shiftrows:n"); / 在中间态的行上, k=state10; / 第0行不变 state10=state11; / 第一行循环左移一个字节 state11=state12; / 第二行循环左移两个字节 state12=state13; / 第三行循环左移三个字节 state13=k; k=state20; state20=state22; state22=k; k=state2
14、1; state21=state23; state23=k; k=state30; state30=state33; state33=state32; state32=state31; state31=k; for(i=0;i<4;i+) /输出到屏幕显示statefor(j=0;j<4;j+)printf("tt%02x ",stateij); printf("n"); printf("n"); return 0; 3列混合mixcolumns()实现逐列混合,方法是s(x)=c(x)*s(x)mod(x4+1)unsi
15、gned char mixcolumns(unsigned char state44) printf("after mixcolumns:n");/ 实现 (02 03 01 01) 与中间态state分别相乘后异或得相应值for(i=0;i<4;i+) / (01 02 03 01) / (01 01 02 03) k=state0i; / (03 01 01 02) temp0 = state0i state1i state2i state3i ; temp1 = state0i state1i ; temp1 = xtime(temp1); state0i =
16、temp1 temp0 ; temp1 = state1i state2i ; temp1 = xtime(temp1); state1i = temp1 temp0 ; temp1 = state2i state3i ; temp1 = xtime(temp1); state2i = temp1 temp0 ; temp1 = state3i k ; temp1 = xtime(temp1); state3i = temp1 temp0 ; for(i=0;i<4;i+) /输出到屏幕显示statefor(j=0;j<4;j+)printf("tt%02x "
17、,stateij); printf("n"); printf("n");return 0;4轮密钥加addroundkey()用于将输入或中间态s的每一列与一个密钥字ki进行按位异或,每一个轮密钥由nb个字组成。unsigned char addroundkey(unsigned char state44,unsigned char w44)printf("addroundkey %d:n",round+); /将中间态state中的每一列与一个密钥字(w44中的一列)进行按位异或for(i=0;i<4;i+) /完了又赋值给s
18、tatefor(j=0;j<4;j+)stateij=wij;for(i=0;i<4;i+) /输出到屏幕显示出来statefor(j=0;j<4;j+)printf("tt%02x ",stateij);printf("n");printf("n"); return 0; 5密钥扩展 通过生成器产生nr+1个轮密钥,每个轮密钥由nb个字组成,共有nb(nr+1)个字。在加密过程中,需要nr+1个轮密钥,需要构造4(nr+1)个32位字。首先将输入的4个字节直接复制到扩展密钥数组的前4个字中,得到w0,w1,w2,w
19、3;然后每次用4个字填充扩展密钥数余下的部分。/keyexpand printf("after keyexpand:n");for(i=4;i<8;i+) if(i%4=0) rotword0=w1i-1; rotword1=w2i-1; rotword2=w3i-1; rotword3=w0i-1; printf("rotword():"); for(j=0;j<4;j+) printf("%02x ",rotwordj); for(j=0;j<4;j+) subwordj=sboxrotwordj; printf
20、("nsubword():"); for(j=0;j<4;j+) printf("%02x ",subwordj); printf("nn"); for(j=0;j<4;j+) rconj=subwordj rconnj ; printf("after rcon():"); for(j=0;j<4;j+) printf("%02x ",rconj); printf("nn");for(j=0;j<4;j+) wji%4=rconj wji-4 ;pri
21、ntf("w%d :",count);for(j=0;j<4;j+) printf(" %02x ",wji%4) ; count+; else for(j=0;j<4;j+)wji%4=wji%4wj(i%4)-1;printf("w%d :",count);for(j=0;j<4;j+) printf(" %02x ",wji%4); count+; printf("nn");printf("密钥扩展 round key:n");for(i=0;i<
22、;4;i+)for(j=0;j<4;j+)printf("tt%02x ",wij);printf("n");printf("n");6逆字节替换与字节代替类似,逆字节代替基于逆s盒实现。unsigned char invsubbytes(unsigned char state44) for(i=0;i<4;i+) /基于逆s盒的映射替代 for(j=0;j<4;j+) stateij = rsboxstateij; printf("after invsubbyte:n"); for(i=0;i&
23、lt;4;i+)for(j=0;j<4;j+) /输出到屏幕显示stateprintf("tt%02x ",stateij); printf("n");printf("n");return 0;7逆行移位与行移位相反,逆行移位将态state的后三行按相反的方向进行移位操作,即第0行保持不变,第1行循环向右移一个字节,第2行循环向右移动两个字节,第3行循环向右移动三个字节。unsigned char invshiftrows(unsigned char state44) k=state13; state13=state12; /对
24、中间态state进行移位操作 state12=state11; / 第0行保持不变 state11=state10; / 第1行循环右移一个字节 state10=k; / 第2行循环右移两个字节 / 第3行循环右移三个字节 k=state20; state20=state22; state22=k; k=state21; state21=state23; state23=k; k=state30; state30=state31; state31=state32; state32=state33; state33=k;printf("after invshiftrows:n"
25、;);for(i=0;i<4;i+) /输出到屏幕显示statefor(j=0;j<4;j+)printf("tt%02x ",stateij); printf("n"); printf("n"); return 0;8逆列混合逆列混淆的处理办法与mixcolumns()类似,每一列都通过与一个固定的多项式d(x)相乘进行交换。unsigned char invmixcolumns(unsigned char state44)printf("after invmixcolumns :n"); /实现(0
26、e 0b 0d 09)与中间态state分别相乘后异或得相应值 for(i=0;i<4;i+) / (09 0e 0b 0d) temp0 = state0i; / (0d 09 0e 0b) temp1 = state1i; / (0b 0d 09 0e) temp2 = state2i; temp3 = state3i; state0i = multiply(temp0, 0x0e) multiply(temp1, 0x0b) multiply(temp2, 0x0d) multiply(temp3, 0x09); state1i = multiply(temp0, 0x09) mu
27、ltiply(temp1, 0x0e) multiply(temp2, 0x0b) multiply(temp3, 0x0d); state2i = multiply(temp0, 0x0d) multiply(temp1, 0x09) multiply(temp2, 0x0e) multiply(temp3, 0x0b); state3i = multiply(temp0, 0x0b) multiply(temp1, 0x0d) multiply(temp2, 0x09) multiply(temp3, 0x0e); for(i=0;i<4;i+) /输出到屏幕显示statefor(j
28、=0;j<4;j+)printf("tt%02x ",stateij);printf("n");printf("n");return 0;9加密加密部分分了两种情况:一种是自动检查加密程序的正确性,之前在程序里给明文和密钥赋上初值,运行程序检验结果是否正确;另一种是用户手动输入32位的十六进制数,进行加密,我是把每一具体项模块化,将功能在每个具体模块中实现,只需要直接调用,视觉效果强,一目了然。 下面是实现加密功能一些关键代码:void aes_encrypt(unsigned char staten, unsigned cha
29、r roundkeyn)message16=0x32,0x43,0xf6,0xa8,0x88,0x5a,0x30,0x8d,0x31,0x31,0x98,0xa2,0xe0,0x37,0x07,0x34;key16=0x2b,0x7e,0x15,0x16,0x28,0xae,0xd2,0xa6,0xab,0xf7,0x15,0x88,0x09,0xcf,0x4f,0x3c; for(i=0;i<4;i+) for(j=0;j<4;j+) / 分别获取明文和密钥 stateji=messagem;wji=keym;m+; .addroundkey(state,w);for(round
30、=2;round<11;round+)printf("第 %d 轮加密 : n",round);subbytes(state); shiftrows(state);mixcolumns(state);keyexpand(w, round);addroundkey(state,w);subbytes(state); /最后一轮shiftrows(state);keyexpand(w, 10);addroundkey(state,w);10解密aes解密也是分成了两个部分,第一部分是在程序中对密文和密钥赋初值,通过与标准对照检查解密过程的正确性;第二部分是用户手动输入密文
31、和密钥,程序对其进行解密,得到最后的明文。解密过程基本如下:1)获取输入的明文和密钥 2)通过密钥扩展过程获取各轮密钥 3)轮密钥加变换过程 4)逆行移位 5)逆字节替代 6)轮密钥加变换 7)逆列混淆47步共9次循环,最后一轮实现46步,完成解密过程。主要代码如下:void aes_decrypt(unsigned char staten, unsigned char wn)key16=0x2b,0x7e,0x15,0x16,0x28,0xae,0xd2,0xa6,0xab,0xf7,0x15,0x88,0x09,0xcf,0x4f,0x3c;cipher16=0x39,0x25,0x84,
32、0x1d,0x02,0xdc,0x09,0xfb,0xdc,0x11,0x85,0x97,0x19,0x6a,0x0b,0x32;printf("%02x ",keyi);printf("n"); /获取密文和密钥 for(i=0;i<4;i+) for(j=0;j<4;j+)stateji=cipherm;wji=keym;m+; keyexpand(w,round ); /获得密钥扩展列表addroundkey(state, w); /首轮for (i = 9; i > 0; i -)/1-9轮 invshiftrows(state
33、);invsubbytes(state);keyexpand(w,round );addroundkey(state, w); invmixcolumns(state);invshiftrows(state); /最后一轮invsubbytes(state); keyexpand(w,0 );addroundkey(state, w);四、实验结果及分析 为检验程序的正确性,需要将结果与标准相对照。下面是程序运行界面: 实验三、rsa算法的实现(2学时)一、实验目的通过实现rsa算法,理解公钥密码机制。二、实验内容利用cc+实现rsa算法的加、解密运算。具体包括:1) 利用扩展的euclid计
34、算 a mod n 的乘法逆元;2) miller-rabin素性测试算法对一个给定的大数进行测试;3) 实现的运算,并计算;4) 利用fermat定理手工计算,并与3)计算的结果对比;5) 实现rsa算法。并对"i love the people's republic of china"加解密。说明:为了方便实现,分组可以小一点,比如两个字母一组。字母及其数字编码字母及其数字编码空格 00n 14a 01o 15b 02p 16c 03q 17d 04r 18e 05s 19f 06t 20g 07u 21h 08v 22i 09w 23j 10x 24k 11y
35、 25l 12z 26m 13三、实验步骤#include <iostream>#include <vector>#include <string>using namespace std;int euclid(int a,int n)/n大于aint x,y,r;x=n;y=a;for(int i=0;)if(y=0)return x;if(y=1)return y; r=x%y;x=y;y=r;double exteneuclid(double a,double n)/利用扩展的euclid计算 a mod n 的乘法逆元double x1=1,x2=0,
36、x3=n,y1=0,y2=1,y3=a,q;double t1,t2,t3;for(int i=0;) if(y3=0) return x3; cout<<"no reverse"<<endl; if(y3=1) return y2; q=int(x3/y3); t1=x1-q*y1; t2=x2-q*y2; t3=x3-q*y3; x1=y1;x2=y2;x3=y3; y1=t1;y2=t2;y3=t3;bool rabin(int a,int n)/miller-rabin素性测试算法对一个给定的大数进行测试vector<int> b
37、;unsigned int n=n-1;for(int i=0,j=1; i+)if(j>n)break;if( (n>> i) & (unsigned int)1 ) b.push_back(1);elseb.push_back(0);j*=2;/将n-1表示成二进制形式for(int k=0;k<b.size();k+)cout<<bk;cout<<endl;int d=1,x=0;for(int ii=b.size()-1;ii>=0;ii-)x=d;d=(d*d)%n;if(d=1&&x!=1&&am
38、p;x!=n-1)return false;if(bii=1)d=(d*a)%n;if(d!=1)return false;return true;double quickindex1(double a,double m,double n)/实现am mod n 的运算vector<int> b;unsigned double n=m;for(int ii=0,j=1;ii+)if(j>n)break;if(n>>ii)& (unsigned double) 1)b.push_back(1);elseb.push_back(0);j*=2;double c
39、=0,d=1;for(int i=b.size()-1;i>=0;i-)c*=2;d=(d*d)-int(d*d)/n)*n;if(bi=1)c+=1;d=(d*a)-int(d*a)/n)*n;return d;void transfer(char cypher,double c)int m100=0;for(int i=0,j=0;cypherj!='0'i+=2)if(cypherj=' ')mi=0;mi+1=0;elsemi=cypherj-64;if(mi<10)mi+1=mi;mi=0;elsemi+1=mi%10;mi=mi/10;j
40、+;for(int k2=0;k2<2*strlen(cypher);k2+)cout<<mk2;cout<<endl;/int c100=0;for(int k=0,n=0;k<2*strlen(cypher);k+=4)cn=mk*1000+mk+1*100+mk+2*10+mk+3;n+;for(;cn-1<1000;)/最后一个数填充零,不过此例可要可不要cn-1*=10;void main()double c100=0;double a100=0;double b100=0;char cypher="i love the peopl
41、e's republic of china"/对“我爱中华人民共和国”加解密 transfer(cypher,c);/字母变数字的过程for(int k1=0;ck1!='0'k1+)cout<<ck1<<" "/选取两个素数p=563,q=823double n=0, fn=0, p=563,q=823,d=0;n=p*q;fn=(q-1)*(p-1);/选e与fn互素for(double e=2;e<fn;e+=3)if(euclid(e,fn)=1)break;d=exteneuclid(e,fn); c
42、out<<endl<<"密码和密钥e d and n:"cout<<e<<" "<<d<<" "<<n<<endl;/加密过程cout<<endl<<"加密:"for(int i=0;ci!='0'i+)ai=quickindex1(ci,e,n);cout<<ai<<" "cout<<endl<<"解密
43、:"/解密过程for(int j=0;aj!='0'j+)bj=quickindex1(aj,d,n);cout<<bj<<" " cout<<endl;四、实验结果及分析程序运行界面如下:附:/移位密码、仿射密码、维吉尼亚密码以及置换密码的源代码:#include "stdafx.h"#include <stdio.h> #include <conio.h> #include <string.h> #include <cctype>#inclu
44、de <malloc.h>#include <iostream>using namespace std;void shift() /*移位密码*/ char c100; int length, i=0, key=0; system("cls"); printf("*shift cipher(移位密码)*nplease input primal sentence(请输入最初的明文-一组英文字母): "); gets(c);length=strlen(c);printf("input the key(026): "
45、); scanf("%d", &key); getchar(); if(key<0) printf("the value of key is error!npress any key to return."); getch(); return; for(i=0; i<length; i+) if(ci>96&&ci<123) ci = (ci+key-97)%26+65; else if(ci>64&&ci<91) ci = (ci+key-65)%26+65; printf(&
46、quot;result is: %sn", c); for(i=0; i<length; i+) if(ci>64&&ci<91) ci = (ci-key-65+26)%26+97; printf("nafter translated the sentence,we can see the primal sentence as follow:n%sn", c); printf("press any key to return(按任何键返回)."); getch(); int gcd(int a, int b)
47、 /*辗转相除法求a,b的最大公因数*/ int k = 0; do k = a%b; a = b; b = k; while(k!=0); return a; int ni(int a, int b) /*求a相对于b的逆*/ int i = 0; while(a*(+i)%b!=1); return i; void affine() /*仿射密码*/ char c100; int length, i=0, ka=0, kb=0, tmp; system("cls"); printf("*affine cipher(仿射密码)*nplease input pri
48、mal sentence(请输入最初的明文): "); gets(c); length = strlen(c); printf("input the key(2 numbers): "); scanf("%d%d", &ka, &kb); getchar(); if(gcd(ka,26)!=1) printf("the value of the key is error!npress any key to return."); return; for(i=0; i<length; i+) if(ci&g
49、t;96&&ci<123) ci = (ka*(ci-97)+kb)%26+65; else if(ci>64&&ci<91) ci = (ka*(ci-65)+kb)%26+65; printf("result is: %sn", c); for(i=0; i<length; i+) if(ci>64&&ci<91) tmp = ni(ka,26)*(ci-65)-kb); if(tmp<0) ci = tmp%26+26+97; else ci = tmp%26+97; printf("nafter translated the sente
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2024面向智能制造专业领域的服务内容资源跨媒体关联规范
- 《食品生物化学》题集
- 职工薪酬的会计处理分录-记账实操
- WPS办公应用(高级)习题及答案汇 ch1 文字文档的高级处理-ch4 WPS协作办公
- 三维数字内容制作-三维动画场景搭建制作流程规范
- 专项24-正多边形与圆-重难点题型
- 音乐教学期末总结
- 饭店服务员聘用合同书(33篇)
- 生物组教研工作计划8篇
- 高三工作计划(17篇)
- 物业及物业管理:提升旅游景区品质
- 财政收支业务管理制度
- 精神科病例分享演讲比赛
- 大学生职业生涯规划测绘地理信息技术专业
- 小学新教材解读培训
- MOOC 全球化与中国文化-西南交通大学 中国大学慕课答案
- 摊位布局规划方案
- 注塑工艺损耗率
- 钢结构漏雨维修方案
- (含附件)ktv承包协议书模板-2024
- (高清版)DZT 0289-2015 区域生态地球化学评价规范
评论
0/150
提交评论