密码学课程设计(格式).doc

上传人:jian****018 文档编号:8777875 上传时间:2020-03-31 格式:DOC 页数:39 大小:637KB
返回 下载 相关 举报
密码学课程设计(格式).doc_第1页
第1页 / 共39页
密码学课程设计(格式).doc_第2页
第2页 / 共39页
密码学课程设计(格式).doc_第3页
第3页 / 共39页
点击查看更多>>
资源描述
南京航空航天大学课 程 设 计 报 告课 程 名 称 密码学课程设计 学 院 计算机科学与技术 年 级 2014 学 生 姓 名 陶超权 学 号 161420330 开 课 时 间 2016 至 2017 学年第 一 学期总 成 绩教师签名实验项目名 称实验一、古典密码成绩一、实验目的通过实现简单的古典密码算法,理解密码学的相关概念如明文(plaintext)、密文(ciphertext)、加密密钥(encryption key)、解密密钥(decryption key)、加密算法(encryption algorithm)、解密算法(decryption algorithm)等。2、 实验内容1)用CC+语言实现单表仿射(Affine)加/解密算法;2)用CC+语言实现统计26个英文字母出现频率的程序;3)利用单表仿射加/解密程序对一段较长的英文文章进行加密,再对明文和密文中字母出现的频率进行统计并作对比,观察有什么规律。 仿射变换:加密:解密:其中,k1和k2为密钥,k1Zq,k2Zq*。3、 实验步骤1)在main函数中构建框架,函数主要分为三部分,加密,解密,计算字符出现频率;2)加密函数encrypt(),首先需要输入两个密钥K1,k2,需要注意k2是和26互质的,所以这里用gcd()函数判断了k2与26的最大公约数,加解密都采用了文件操作,明文和密文都保存在文件中,这里加密时根据ascii码,对大小字母分别加密,其他字符则保持不变;3)解密函数decode(),和加密函数类似,需要注意解密要用到密钥K2的逆元,所以这里用函数inverse_k2()进行了逆元的求解,另外需要注意的是解密运算过程中可能出现数值为负数的情况,在模运算下应该将它们重新置为整数。4)计算字符频率函数calculateCharFreq(),这里只对大小字母进行统计,不计其他字符。源代码:* main.cpp *#include#includeint main() void encrypt(); void decode(); void calculateCharFreq(); int choice; printf(please input your choice:n); printf(t1. encryptnt2.decodent3.calculate character frequencent4.quit&exitn); scanf(%d,&choice); getchar(); while(1) switch(choice) case 1: encrypt(); break; case 2: decode(); break; case 3: calculateCharFreq(); break; case 4: return 0; default:break; printf(please input your choice:n); printf(t1. encryptnt2.decodent3.calculate character frequencent4.quit&exitn); scanf(%d,&choice); getchar(); return 0;* encrypt.cpp *#include#includevoid encrypt() int gcd(int,int); printf(please input secret keyn); printf(k1:); int k1,k2; scanf(%d,&k1); getchar(); while(k1=26) printf(illegal k1!please input agian!n); printf(k1:); scanf(%d,&k1); getchar(); printf(k2:); scanf(%d,&k2); getchar(); while(gcd(k2,26)!=1) printf(illegal k2!please input agian!); printf(k2:); scanf(%d,&k2); getchar(); / char plainText100=0; / char cypherText100=0; printf(open the plain text filen); /scanf(%s,plainText); FILE *fplain,*fcypher; if(fplain =fopen(plain.txt,a+)=NULL) printf(cant open plain.txt!n); exit(0); if(fcypher = fopen(cypher.txt,a)=NULL) printf(cant open cypher.txt!n); exit(0); /int i; char plainText = fgetc(fplain); char cypherText; /for(i=0; plainTexti!=0; i+) / printf(%c,plainText); while(plainText != EOF) / printf(old:%dn,plainTexti); if(65=plainText& plainText=90 ) / printf(.); / plainTexti-=65; cypherText = (plainText-65)*k2+k1)%26+65; fputc(cypherText,fcypher); / printf(new:%dn,cypherTexti); else if(97=plainText & plainText=122 ) /plainTexti-=97; cypherText = (plainText-97)*k2+k1)%26+97; fputc(cypherText,fcypher); / printf(new:%dn,cypherTexti); else cypherText=plainText; fputc(cypherText,fcypher); plainText = fgetc(fplain); / printf(%ct%c,plainTexti,cypherTexti); fclose(fplain); fclose(fcypher); printf(cipher text has been written into cypher.txt!n); / printf(%snn,cypherText);* decode.cpp *#include#includevoid decode() int gcd(int ,int); int inverse(int);/ char cypherText100=0;/ char plainText200=0; printf(please input secret keyn); printf(k1:); int k1,k2; scanf(%d,&k1); getchar(); while(k1=26) printf(illegal k1!please input agian!n); printf(k1:); scanf(%d,&k1); getchar(); printf(k2:); scanf(%d,&k2); getchar(); while(gcd(k2,26)!=1) printf(illegal k2!please input agian!); printf(k2:); scanf(%d,&k2); getchar(); int inverse_k2 = inverse(k2); printf(open the cypher txt!n);/ scanf(%s,cypherText); FILE *fplain,*fcypher; if(fplain =fopen(plain1.txt,a)=NULL) printf(cant open plain.txt!n); exit(0); if(fcypher = fopen(cypher.txt,r)=NULL) printf(cant open cypher.txt!n); exit(0); /int i; char cypherText = fgetc(fcypher); char plainText; /for(i=0; plainTexti!=0; i+) / printf(%c,plainText);/ int i; / for(i=0; cypherTexti!=0; i+) while(cypherText!=EOF) / printf(old:%dn,plainTexti); if(65=cypherText& cypherText=90 ) / printf(.); / plainTexti-=65; int t= cypherText-65-k1 ; if(t0) int i=1; while(t0) t+=26 * i ; i+; plainText = (t*inverse_k2)%26)+65; fputc(plainText,fplain); / printf(new:%dn,cypherTexti); else if(97=cypherText & cypherText=122 ) /plainTexti-=97; int t= cypherText-97-k1 ; if(t0) int i=1; while(t0) t+=26 * i ; i+; plainText = (t*inverse_k2)%26)+97; / printf(new:%dn,plainText); fputc(plainText,fplain); else plainText=cypherText; fputc(plainText,fplain); /printf(%ct%c,plainTexti,cypherTexti); cypherText= fgetc(fcypher); fclose(fplain); fclose(fcypher); printf(plain text has been written into plain1.txt!n); / printf(%snn,plainText);int gcd(int x, int y) int t=0; /int t1=x; /int t2=y; while(y!=0) t = x%y; x = y; y = t; /printf(%d,x); return x;int inverse(int x) int i; for( i=0; i26; i+) if(i*x)%26=1) break; / printf(%dn,i); return i;* charFreq.cpp *#include#includevoid calculateCharFreq() char filename10=0; char ch; FILE * fp; float sum=0; float freq26=0; float charNum26=0; printf(please input the filename you wanna staticstic frequence:n ); /getchar(); gets(filename); /getchar(); if(fp =fopen(filename,r)=NULL) printf(cant open %s!n,filename); exit(0); ch = fgetc(fp); while(ch != EOF) if(a=ch &ch=A & ch=Z) charNumch-65+; sum+; /printf(%cn,ch); ch=fgetc(fp); fclose(fp); /char t = 0; int count=0; for(int i=0;i26;i+) freqi = charNumi/sum; /printf(charNUm:%ftsum:%ftfreq:%fn,charNumi,sum,freqi); printf(%c(%c):%.3ft,i+65,i+97,freqi); count+; if(count=6) printf(n); count=0; printf(nn);四、实验结果及分析这里明文选取了普朗特的就职演说,得到明文密文各个字符的频率如下:可以看出,在明文中,出现频率最高的是e:0.123 , t:0.089, a:0.082, o:0.081, n:0.070 在密文中,出现频率最高的是O:0.123, h:0.089, c:0.082, s:0.081, p:0.070经过计算可以知道字符o h c s p正是字符 e t a o n的加密变换由此可知,单表仿射加密是一种线性的加密,加密后字符的统计特性没有发生变化,只是字符不同而已。实验项目名 称实验二、序列密码成绩一、实验目的通过实现简单的线性反馈移位寄存器(LFSR),理解LFSR的工作原理、本原多项式的重要意义。3、 实验内容1)利用CC+语言实现给定的LFSR;2)通过不同初始状态生成相应的序列,并观察它们的周期有什么特点;3)利用生成的序列对文本进行加/解密(按对应位作模2加运算)。给定的LFSR为:4、 实验步骤1) 在main函数中构建框架,分为三部分:初始化,打印序列,加密文本2) 初始化lfsr,这里用一个长度为5的整型数组来模拟移位寄存器,初始化时也只需要将这五个数组元素初始化即可。3) 打印序列,从移位寄存器的图示可以得知反馈函数为f = a4+a1;程序执行时先将a4+a1的结果保存,然后顺次移位a1-a2,a2-a3,a3-a4,a4-a4+a1.因为lfsr一定具有周期性,且周期最大为2n-1,所以这里我们连续输出序列长度为2n+5,由此来观察周期性4) 在对文本进行加密时,每次从文件中读取一个数字0或者1,然后用lfsr顺次产生一个元素,进行模二加得到密文源代码:#include #include#include#define NUM 5/* run this program using the console pauser or add your own getch, system(pause) or input loop */int main() void init_lfsr(int *); void print_sequence(int *); void encrypt(int *); int regNUM ; int choice ; while(1) printf(nplease input your choice:n); printf(t1.init lfsr 2.print sequence 3.encrpt text 4.exitn); scanf(%d,&choice); getchar(); switch(choice) case 1: init_lfsr(reg); break; case 2: print_sequence(reg); break; case 3: encrypt(reg); break; case 4: exit(2); return 0;void init_lfsr(int *reg) void print_sequence(int *r); printf(please input initial sequence:n); for(int i=0; iNUM; i+) scanf(%d,®i); regi%=2; getchar(); /*for(int i=0; i2; i+) for(int j=0; j2; j+) for(int k=0; k2; k+) for(int m=0; m2; m+) for(int n=0; n2; n+) reg0=i;reg1=j;reg2=k;reg3=m,reg4=n; printf(ninitial sequence is :n); for(int i=0; iNUM; i+) printf(%d,regi); /getchar(); printf(n); print_sequence(reg); */ printf(initial sequence is :n); for(int i=0; iNUM; i+) printf(%d,regi); /getchar(); printf(n);void print_sequence(int *r) int temp ; int count = 0 ; int change_row = 0; int *reg = (int *)malloc(NUM*sizeof(int); if(reg = NULL) exit(4); for(int i=0; iNUM; i+) regi = ri; while(count = pow(2,NUM)+5) printf(%d ,reg0); change_row + ; if(change_row % 20 = 0) printf(n) ; temp = (reg0+reg3)%2; int i; for( i=0; iNUM-1; i+) regi = regi+1 ; regi = temp ; count+ ; free(reg); void encrypt(int *r) FILE *fp1,*fp2 ; int plain ; int cypher ; int temp ; int *reg = (int *)malloc(NUM*sizeof(int); if(reg = NULL) exit(4); for(int i=0; iNUM; i+) regi = ri; if(fp1 = fopen(plain.txt,r)=NULL) printf(cant open file plian.txt!); exit(0); if(fp2 = fopen(cypher.txt,a)=NULL) printf(cant open file cypher.txt!); exit(1); / fseek(fp1,0L,SEEK_SET); / fscanf(fp1,%d,&plain); char ch1; ch0 = fgetc(fp1);/ printf(char:%cn,ch0); plain = atoi(ch);/ printf(plain:%dn,plain); while(!feof(fp1) cypher = (plain + reg0)%2 ; fprintf(fp2,%d,cypher); printf(%d,cypher); temp = (reg0+reg3)%2; int i; for( i=0; iNUM-1; i+) regi = regi+1 ; regi = temp ; /fscanf(fp1,%d,&plain); ch0 = fgetc(fp1);/ printf(char:%cn,ch0); plain = atoi(ch);/ printf(plain:%dn,plain); fclose(fp1); fclose(fp2); free(reg); 四、实验结果及分析对源程序稍作修改,可以得到每个初始序列对应生成序列,如下:可以看出,除去第一个初始序列为全0的,其他31个序列的周期都是31,也即lfsr的最大周期25-1对文本进行加密,首先从文本plain.txt中读取明文,然后利用之前初始化得到的序列对明文进行加密,将结果写入cypher.txt中,同时打印输出到控制台,结果如下:实验项目名 称实验三、DES算法的实现成绩一、实验目的通过实现DES/AES算法,加深对DES/AES算法的理解,同时学习组合密码常用的代换、移位等运算的实现。4、 实验内容1)利用CC+实现DES/AES算法的加、解密运算。5、 实验步骤(1) 初始置换,用初始置换IP表对明文进行置换(2) 密钥置换,除去每个字节的第八位,剩下56位密钥,然后在DES的每一轮中,从56位密钥中选出48位(3) 扩展置换,将数据的右半部份从32位扩展到48位(4) S盒代替,将上述的48位输入再次转换位32位输出(5) 逆初始置换源代码:#include #include time.h#include stdlib.h#include string.h static int IP_Table64 = 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, 56,48,40,32,24,16,8,0, 58,50,42,34,26,18,10,2, 60,52,44,36,28,20,12,4, 62,54,46,38,30,22,14,6; static int IP_1_Table64 = 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, 32,0,40,8,48,16,56,24;static int E_Table48 = 31, 0, 1, 2, 3, 4, 3, 4, 5, 6, 7, 8, 7, 8,9,10,11,12, 11,12,13,14,15,16, 15,16,17,18,19,20, 19,20,21,22,23,24, 23,24,25,26,27,28, 27,28,29,30,31, 0;static int P_Table32 = 15,6,19,20,28,11,27,16, 0,14,22,25,4,17,30,9, 1,7,23,13,31,26,2,8, 18,12,29,5,21,10,3,24;static int S8416 =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, 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, 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, 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, 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, 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, 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, 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 int PC_156 = 56,48,40,32,24,16,8, 0,57,49,41,33,25,17, 9,1,58,50,42,34,26, 18,10,2,59,51,43,35, 62,54,46,38,30,22,14, 6,61,53,45,37,29,21, 13,5,60,52,44,36,28, 20,12,4,27,19,11,3;static int PC_248 = 13,16,10,23,0,4,2,27, 14,5,20,9,22,18,11,3, 25,7,15,6,26,19,12,1, 40,51,30,36,46,54,29,39, 50,44,32,46,43,48,38,55, 33,52,45,41,49,35,28,31;static int MOVE_TIMES16 = 1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1;static unsigned char SubKey1648;void ByteToBit(unsigned char *ch,unsigned char *bit);void BitToByte(unsigned char *bit,unsigned char *ch);void Xor(unsigned char *A,unsigned char *B,int len);void Transform(unsigned char *str,unsigned char *change,int *table,int len);void Rotatel(unsigned char *str, int loop);void MakeSubKeys(unsigned char *k);void F_fun(unsigned char *M,unsigned char *key);void DES_Encrypt(unsigned char *plain,unsigned char *cipher);void DES_Decrypt(unsigned char *cipher,unsigned char *plain);void ByteToBit(unsigned char* ch,unsigned char* bit) int i,j; for(i=0; i8; i+) for(j = 0;jj)&1; void BitToByte(unsigned char *bit, unsigned char *ch) int i,j; memset(ch,0,9); for(i=0; i8; i+) for(j = 0;j 8; j+) chi |= *(bit + j+8*i)j; void Transform(unsigned char *str,unsigned char *change,int *table,int len) int i; for(i=0;ilen;i+) changei=strtablei; void Rotatel(unsigned char *str, int loop) static unsigned char Tmp256; memcpy(Tmp, str, loop); memcpy(str, str+loop, 28-loop); memcpy(str+28-loop, Tmp, loop);void MakeSubKeys(unsigned char *k) unsigned char str64,key64,*KL=&key0,*KR=&key28; int i; ByteToBit(k,str); Transform(str,key,PC_1,56); for(i=0;i16;i+) Rotatel(KL,MOVE_TIMESi); Rotatel(KR,MOVE_TIMESi); Transform(key,SubKeyi,PC_2,48); void DES_Encrypt(unsigned char *plain,unsigned char *cipher) unsigned char str256; int i; unsigned char M64,*ML=&M0,*MR=&M32,Tmp32; ByteToBit(plain,str); Transform(str,M,IP_Table,64); for(i=0; i=0; i-) memcpy(Tmp, ML, 32); F_fun(ML, SubKeyi); Xor(ML, MR,32); memcpy(MR, Tmp, 32); Transform(M, str, IP_1_Table, 64); BitToByte(str, plain);void F_fun(unsigned char *M,unsigned char *key) unsigned char str48,out48; int i,f; unsigned char j,k,g; Transform(M, str, E_Table, 48); Xor(str,key,48); memset(out,0,49); for(i=0; i8; i+) g=i*6; j = (strg1) + strg+5; k = (strg+13) + (strg+22) + (strg+31) + strg+4; f
展开阅读全文
相关资源
相关搜索

当前位置:首页 > 图纸专区 > 大学资料


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!