[关闭]
@rg070836rg 2017-10-10T16:46:05.000000Z 字数 5922 阅读 3315

网络安全第二次实验(第三次作业) 陈实 SA17011008

USTC网络安全


  1. SA17011008 陈实 20171010 实验 2

一、实验要求

  1. 修改例程cryptoDemo.cppencfile.cpp,从命令行接受参数3个字符串类型的参数:参数1,参数2,参数3。参数1=enc表示加密,参数1=dec表示解密;参数2为待加密、解密的文件;参数3为密码。

二、实验准备

  1. VirtualBox
  2. Ubuntu16.04
  3. gcc

安装openssl库,使用命令:

  1. sudo apt-get install libssl-dev

此处输入图片的描述

三、实验过程

3.1 试验cryptoDemo.cpp效果

  1. //程序源码
  2. // cryptoDemo.cpp : Defines the entry point for the console application.
  3. // Windows: cl cryptoDemo.cpp
  4. // Linux: gcc -o cryptoDemo cryptoDemo.cpp -lcrypto
  5. #include <memory.h>
  6. #include <stdio.h>
  7. #include <string.h>
  8. #include <stdlib.h>
  9. #include "openssl/aes.h"
  10. #pragma comment(lib,"libeay32.lib")
  11. void testAes(char inString[], int inLen, char passwd[], int pwdLen)
  12. {
  13. int i,j, len, nLoop, nRes;
  14. char enString[1024];
  15. char deString[1024];
  16. unsigned char buf[16];
  17. unsigned char buf2[16];
  18. unsigned char aes_keybuf[32];
  19. AES_KEY aeskey;
  20. // 准备32字节(256位)的AES密码字节
  21. memset(aes_keybuf,0x90,32);
  22. if(pwdLen<32){ len=pwdLen; } else { len=32;}
  23. for(i=0;i<len;i++) aes_keybuf[i]=passwd[i];
  24. // 输入字节串分组成16字节的块
  25. nLoop=inLen/16; nRes = inLen%16;
  26. // 加密输入的字节串
  27. AES_set_encrypt_key(aes_keybuf,256,&aeskey);
  28. for(i=0;i<nLoop;i++){
  29. memset(buf,0,16);
  30. for(j=0;j<16;j++) buf[j]=inString[i*16+j];
  31. AES_encrypt(buf,buf2,&aeskey);
  32. for(j=0;j<16;j++) enString[i*16+j]=buf2[j];
  33. }
  34. if(nRes>0){
  35. memset(buf,0,16);
  36. for(j=0;j<nRes;j++) buf[j]=inString[i*16+j];
  37. AES_encrypt(buf,buf2,&aeskey);
  38. for(j=0;j<16;j++) enString[i*16+j]=buf2[j];
  39. //puts("encrypt");
  40. }
  41. enString[i*16+j]=0;
  42. // 密文串的解密
  43. AES_set_decrypt_key(aes_keybuf,256,&aeskey);
  44. for(i=0;i<nLoop;i++){
  45. memset(buf,0,16);
  46. for(j=0;j<16;j++) buf[j]=enString[i*16+j];
  47. AES_decrypt(buf,buf2,&aeskey);
  48. for(j=0;j<16;j++) deString[i*16+j]=buf2[j];
  49. }
  50. if(nRes>0){
  51. memset(buf,0,16);
  52. for(j=0;j<16;j++) buf[j]=enString[i*16+j];
  53. AES_decrypt(buf,buf2,&aeskey);
  54. for(j=0;j<16;j++) deString[i*16+j]=buf2[j];
  55. //puts("decrypt");
  56. }
  57. deString[i*16+nRes]=0;
  58. //比较解密后的串是否与输入的原始串相同
  59. if(memcmp(inString,deString,strlen(inString))==0)
  60. { printf("test success\r\n");} else { printf("test fail\r\n");}
  61. printf("The original string is:\n %s ", inString);
  62. printf("The encrypted string is:\n %s ", enString);
  63. printf("The decrypted string is:\n %s ", deString);
  64. }
  65. int main(int argc, char* argv[])
  66. {
  67. char inString[] = "This is a sample. I am a programer.\n";
  68. char passwd[] = "0123456789ABCDEFGHIJK";
  69. testAes(inString, strlen(inString), passwd, strlen(passwd));
  70. return 0;
  71. }

利用gcc编译,并执行

  1. gcc -o cryp cryptoDemo.cpp -lcrypto
  2. ./cryp

此处输入图片的描述

3.2 改写原demo

修改部分:拆解原demo,加上文件读写即可,代码如下

  1. // cryptoDemo.cpp : Defines the entry point for the console application.
  2. // Windows: cl cryptoDemo.cpp
  3. // Linux: gcc -o cryptoDemo cryptoDemo.cpp -lcrypto
  4. // Linux: gcc -o encfile encfile.cpp -lcrypto
  5. // chen SA17011008
  6. #include <memory.h>
  7. #include <stdio.h>
  8. #include <string.h>
  9. #include <stdlib.h>
  10. #include <openssl/aes.h>
  11. #pragma comment(lib,"libeay32.lib")
  12. void encrypt(char *filename, char passwd[], int pwdLen) //加密
  13. {
  14. char inString[1024];
  15. char enFile[1024]; //加密后的文件名
  16. strcpy(enFile,filename);
  17. strcat(enFile,"_encrypt"); //加密后的文件名
  18. //文件读取
  19. FILE *fp=fopen(filename,"r");
  20. if(fp==NULL)
  21. {
  22. printf("文件%s打开错误\n",filename);
  23. fclose(fp);
  24. return;
  25. }
  26. char c=fgetc(fp); //从fp所指文件的当前指针位置读取一个字符
  27. int i=0;
  28. while(c!=EOF)
  29. {
  30. inString[i++]=c;
  31. c=fgetc(fp);
  32. }
  33. inString[i]=0; //输入结束符
  34. fclose(fp);
  35. //加密(demo部分代码)
  36. int j, len, nLoop, nRes;
  37. char enString[1024];
  38. unsigned char buf[16];
  39. unsigned char buf2[16];
  40. unsigned char aes_keybuf[32];
  41. AES_KEY aeskey;
  42. int inLen=strlen(inString); //原始字符串的长度
  43. // 准备32字节(256位)的AES密码字节
  44. memset(aes_keybuf,0x90,32);
  45. if(pwdLen<32){ len=pwdLen; } else { len=32;}
  46. for(i=0;i<len;i++) aes_keybuf[i]=passwd[i];
  47. // 输入字节串分组成16字节的块
  48. nLoop=inLen/16; nRes = inLen%16;
  49. // 加密输入的字节串
  50. AES_set_encrypt_key(aes_keybuf,256,&aeskey);
  51. for(i=0;i<nLoop;i++){
  52. memset(buf,0,16);
  53. for(j=0;j<16;j++) buf[j]=inString[i*16+j];
  54. AES_encrypt(buf,buf2,&aeskey);
  55. for(j=0;j<16;j++) enString[i*16+j]=buf2[j];
  56. }
  57. if(nRes>0){
  58. memset(buf,0,16);
  59. for(j=0;j<nRes;j++) buf[j]=inString[i*16+j];
  60. AES_encrypt(buf,buf2,&aeskey);
  61. for(j=0;j<16;j++) enString[i*16+j]=buf2[j];
  62. //puts("encrypt");
  63. }
  64. enString[i*16+j]=0;
  65. //写入文件
  66. FILE *fpw=fopen(enFile,"w");
  67. if(fpw==NULL)
  68. {
  69. printf("不能写入%s\n",enFile);
  70. fclose(fpw);
  71. return;
  72. }
  73. int len1=strlen(enString);
  74. for(int i=0;i<len1;i++)
  75. {
  76. fputc(enString[i],fpw);
  77. }
  78. fclose(fpw);
  79. }
  80. void decrypt(char *filename, char passwd[], int pwdLen) //解密
  81. {
  82. char enString[1024]; //从文件中读取的密文串
  83. char deFile[1024]; //解密后的文件名
  84. strcpy(deFile,filename);
  85. strcat(deFile,"_decrypt"); //解密后的文件名
  86. //文件读取
  87. FILE *fp=fopen(filename,"r");
  88. if(fp==NULL)
  89. {
  90. printf("文件%s打开错误\n",filename);
  91. fclose(fp);
  92. return;
  93. }
  94. char c=fgetc(fp); //从fp所指文件的当前指针位置读取一个字符
  95. int i=0;
  96. while(c!=EOF)
  97. {
  98. enString[i++]=c;
  99. c=fgetc(fp);
  100. }
  101. enString[i]=0; //输入结束符
  102. fclose(fp);
  103. //解密
  104. int j, len, nLoop, nRes;
  105. char deString[1024]; //解密后的字符串
  106. unsigned char buf[16];
  107. unsigned char buf2[16];
  108. unsigned char aes_keybuf[32];
  109. AES_KEY aeskey;
  110. // 准备32字节(256位)的AES密码字节
  111. memset(aes_keybuf,0x90,32);
  112. if(pwdLen<32){ len=pwdLen; } else { len=32;}
  113. for(i=0;i<len;i++) aes_keybuf[i]=passwd[i];
  114. int inLen=strlen(enString);
  115. // 密文字节串分组成16字节的块
  116. nLoop=inLen/16; nRes = inLen%16;
  117. // 密文串的解密
  118. AES_set_decrypt_key(aes_keybuf,256,&aeskey);
  119. for(i=0;i<nLoop;i++){
  120. memset(buf,0,16);
  121. for(j=0;j<16;j++) buf[j]=enString[i*16+j];
  122. AES_decrypt(buf,buf2,&aeskey);
  123. for(j=0;j<16;j++) deString[i*16+j]=buf2[j];
  124. }
  125. if(nRes>0){
  126. memset(buf,0,16);
  127. for(j=0;j<16;j++) buf[j]=enString[i*16+j];
  128. AES_decrypt(buf,buf2,&aeskey);
  129. for(j=0;j<16;j++) deString[i*16+j]=buf2[j];
  130. //puts("decrypt");
  131. }
  132. deString[i*16+nRes]=0;
  133. //写入文件
  134. FILE *fpw=fopen(deFile,"w");
  135. if(fpw==NULL)
  136. {
  137. printf("不能写入%s.\n",deFile);
  138. fclose(fpw);
  139. return;
  140. }
  141. int len1=strlen(deString);
  142. for(i=0;i<len1;i++)
  143. {
  144. fputc(deString[i],fpw);
  145. }
  146. fclose(fpw);
  147. }
  148. int main(int argc, char* argv[])
  149. {
  150. // 检测参数是否为4个
  151. if(argc!=4)
  152. printf("Error format!\n");
  153. //获取参数
  154. char *type=argv[1];
  155. char *filename=argv[2];
  156. char *passwd=argv[3];
  157. //加密&解密
  158. if(strcmp(type,"enc")==0)
  159. encrypt(filename,passwd,strlen(passwd));
  160. else if(strcmp(type,"dec")==0)
  161. decrypt(filename,passwd,strlen(passwd));
  162. else
  163. printf("parameter error!\n");
  164. return 0;
  165. }

编译encfile.cpp

写完之后,在终端下,执行下面的操作,进行编译,生成encfile

  1. gcc -o encfile encfile.cpp -lcrypto

此处输入图片的描述

明文文件内容如下:
此处输入图片的描述

执行加密

  1. ./encfile enc file 0123456789ABCDEFGHIJK

密文文件内容如下:
此处输入图片的描述

执行解密

  1. ./encfile dec file_encrypt 0123456789ABCDEFGHIJK

此处输入图片的描述

可以看出,加密前后的内容是一致的。

四、实验心得

通过这次试验,对 aes 加密解密有了简单的了解,并简单实验了加密和解密过程,将处理后的信息保存下来。通过这次实验自己亲手体会了其中加密和解密的过程,收获很大。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注