@rg070836rg
2017-10-10T08:46:05.000000Z
字数 5922
阅读 3623
USTC网络安全
SA17011008 陈实 2017年10月10日 实验 2
修改例程cryptoDemo.cpp为encfile.cpp,从命令行接受参数3个字符串类型的参数:参数1,参数2,参数3。参数1=enc表示加密,参数1=dec表示解密;参数2为待加密、解密的文件;参数3为密码。
VirtualBoxUbuntu16.04gcc
安装openssl库,使用命令:
sudo apt-get install libssl-dev

//程序源码// cryptoDemo.cpp : Defines the entry point for the console application.// Windows: cl cryptoDemo.cpp// Linux: gcc -o cryptoDemo cryptoDemo.cpp -lcrypto#include <memory.h>#include <stdio.h>#include <string.h>#include <stdlib.h>#include "openssl/aes.h"#pragma comment(lib,"libeay32.lib")void testAes(char inString[], int inLen, char passwd[], int pwdLen){int i,j, len, nLoop, nRes;char enString[1024];char deString[1024];unsigned char buf[16];unsigned char buf2[16];unsigned char aes_keybuf[32];AES_KEY aeskey;// 准备32字节(256位)的AES密码字节memset(aes_keybuf,0x90,32);if(pwdLen<32){ len=pwdLen; } else { len=32;}for(i=0;i<len;i++) aes_keybuf[i]=passwd[i];// 输入字节串分组成16字节的块nLoop=inLen/16; nRes = inLen%16;// 加密输入的字节串AES_set_encrypt_key(aes_keybuf,256,&aeskey);for(i=0;i<nLoop;i++){memset(buf,0,16);for(j=0;j<16;j++) buf[j]=inString[i*16+j];AES_encrypt(buf,buf2,&aeskey);for(j=0;j<16;j++) enString[i*16+j]=buf2[j];}if(nRes>0){memset(buf,0,16);for(j=0;j<nRes;j++) buf[j]=inString[i*16+j];AES_encrypt(buf,buf2,&aeskey);for(j=0;j<16;j++) enString[i*16+j]=buf2[j];//puts("encrypt");}enString[i*16+j]=0;// 密文串的解密AES_set_decrypt_key(aes_keybuf,256,&aeskey);for(i=0;i<nLoop;i++){memset(buf,0,16);for(j=0;j<16;j++) buf[j]=enString[i*16+j];AES_decrypt(buf,buf2,&aeskey);for(j=0;j<16;j++) deString[i*16+j]=buf2[j];}if(nRes>0){memset(buf,0,16);for(j=0;j<16;j++) buf[j]=enString[i*16+j];AES_decrypt(buf,buf2,&aeskey);for(j=0;j<16;j++) deString[i*16+j]=buf2[j];//puts("decrypt");}deString[i*16+nRes]=0;//比较解密后的串是否与输入的原始串相同if(memcmp(inString,deString,strlen(inString))==0){ printf("test success\r\n");} else { printf("test fail\r\n");}printf("The original string is:\n %s ", inString);printf("The encrypted string is:\n %s ", enString);printf("The decrypted string is:\n %s ", deString);}int main(int argc, char* argv[]){char inString[] = "This is a sample. I am a programer.\n";char passwd[] = "0123456789ABCDEFGHIJK";testAes(inString, strlen(inString), passwd, strlen(passwd));return 0;}
利用gcc编译,并执行
gcc -o cryp cryptoDemo.cpp -lcrypto./cryp

修改部分:拆解原demo,加上文件读写即可,代码如下
// cryptoDemo.cpp : Defines the entry point for the console application.// Windows: cl cryptoDemo.cpp// Linux: gcc -o cryptoDemo cryptoDemo.cpp -lcrypto// Linux: gcc -o encfile encfile.cpp -lcrypto// chen SA17011008#include <memory.h>#include <stdio.h>#include <string.h>#include <stdlib.h>#include <openssl/aes.h>#pragma comment(lib,"libeay32.lib")void encrypt(char *filename, char passwd[], int pwdLen) //加密{char inString[1024];char enFile[1024]; //加密后的文件名strcpy(enFile,filename);strcat(enFile,"_encrypt"); //加密后的文件名//文件读取FILE *fp=fopen(filename,"r");if(fp==NULL){printf("文件%s打开错误\n",filename);fclose(fp);return;}char c=fgetc(fp); //从fp所指文件的当前指针位置读取一个字符int i=0;while(c!=EOF){inString[i++]=c;c=fgetc(fp);}inString[i]=0; //输入结束符fclose(fp);//加密(demo部分代码)int j, len, nLoop, nRes;char enString[1024];unsigned char buf[16];unsigned char buf2[16];unsigned char aes_keybuf[32];AES_KEY aeskey;int inLen=strlen(inString); //原始字符串的长度// 准备32字节(256位)的AES密码字节memset(aes_keybuf,0x90,32);if(pwdLen<32){ len=pwdLen; } else { len=32;}for(i=0;i<len;i++) aes_keybuf[i]=passwd[i];// 输入字节串分组成16字节的块nLoop=inLen/16; nRes = inLen%16;// 加密输入的字节串AES_set_encrypt_key(aes_keybuf,256,&aeskey);for(i=0;i<nLoop;i++){memset(buf,0,16);for(j=0;j<16;j++) buf[j]=inString[i*16+j];AES_encrypt(buf,buf2,&aeskey);for(j=0;j<16;j++) enString[i*16+j]=buf2[j];}if(nRes>0){memset(buf,0,16);for(j=0;j<nRes;j++) buf[j]=inString[i*16+j];AES_encrypt(buf,buf2,&aeskey);for(j=0;j<16;j++) enString[i*16+j]=buf2[j];//puts("encrypt");}enString[i*16+j]=0;//写入文件FILE *fpw=fopen(enFile,"w");if(fpw==NULL){printf("不能写入%s\n",enFile);fclose(fpw);return;}int len1=strlen(enString);for(int i=0;i<len1;i++){fputc(enString[i],fpw);}fclose(fpw);}void decrypt(char *filename, char passwd[], int pwdLen) //解密{char enString[1024]; //从文件中读取的密文串char deFile[1024]; //解密后的文件名strcpy(deFile,filename);strcat(deFile,"_decrypt"); //解密后的文件名//文件读取FILE *fp=fopen(filename,"r");if(fp==NULL){printf("文件%s打开错误\n",filename);fclose(fp);return;}char c=fgetc(fp); //从fp所指文件的当前指针位置读取一个字符int i=0;while(c!=EOF){enString[i++]=c;c=fgetc(fp);}enString[i]=0; //输入结束符fclose(fp);//解密int j, len, nLoop, nRes;char deString[1024]; //解密后的字符串unsigned char buf[16];unsigned char buf2[16];unsigned char aes_keybuf[32];AES_KEY aeskey;// 准备32字节(256位)的AES密码字节memset(aes_keybuf,0x90,32);if(pwdLen<32){ len=pwdLen; } else { len=32;}for(i=0;i<len;i++) aes_keybuf[i]=passwd[i];int inLen=strlen(enString);// 密文字节串分组成16字节的块nLoop=inLen/16; nRes = inLen%16;// 密文串的解密AES_set_decrypt_key(aes_keybuf,256,&aeskey);for(i=0;i<nLoop;i++){memset(buf,0,16);for(j=0;j<16;j++) buf[j]=enString[i*16+j];AES_decrypt(buf,buf2,&aeskey);for(j=0;j<16;j++) deString[i*16+j]=buf2[j];}if(nRes>0){memset(buf,0,16);for(j=0;j<16;j++) buf[j]=enString[i*16+j];AES_decrypt(buf,buf2,&aeskey);for(j=0;j<16;j++) deString[i*16+j]=buf2[j];//puts("decrypt");}deString[i*16+nRes]=0;//写入文件FILE *fpw=fopen(deFile,"w");if(fpw==NULL){printf("不能写入%s.\n",deFile);fclose(fpw);return;}int len1=strlen(deString);for(i=0;i<len1;i++){fputc(deString[i],fpw);}fclose(fpw);}int main(int argc, char* argv[]){// 检测参数是否为4个if(argc!=4)printf("Error format!\n");//获取参数char *type=argv[1];char *filename=argv[2];char *passwd=argv[3];//加密&解密if(strcmp(type,"enc")==0)encrypt(filename,passwd,strlen(passwd));else if(strcmp(type,"dec")==0)decrypt(filename,passwd,strlen(passwd));elseprintf("parameter error!\n");return 0;}
写完之后,在终端下,执行下面的操作,进行编译,生成encfile
gcc -o encfile encfile.cpp -lcrypto

明文文件内容如下:

./encfile enc file 0123456789ABCDEFGHIJK
密文文件内容如下:

./encfile dec file_encrypt 0123456789ABCDEFGHIJK

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