@rg070836rg
2017-10-10T16:46:05.000000Z
字数 5922
阅读 3334
USTC网络安全
SA17011008 陈实 2017年10月10日 实验 2
修改例程cryptoDemo.cpp为encfile.cpp,从命令行接受参数3个字符串类型的参数:参数1,参数2,参数3。参数1=enc表示加密,参数1=dec表示解密;参数2为待加密、解密的文件;参数3为密码。
VirtualBox
Ubuntu16.04
gcc
安装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));
else
printf("parameter error!\n");
return 0;
}
写完之后,在终端下,执行下面的操作,进行编译,生成encfile
gcc -o encfile encfile.cpp -lcrypto
明文文件内容如下:
./encfile enc file 0123456789ABCDEFGHIJK
密文文件内容如下:
./encfile dec file_encrypt 0123456789ABCDEFGHIJK
可以看出,加密前后的内容是一致的。
通过这次试验,对 aes 加密解密有了简单的了解,并简单实验了加密和解密过程,将处理后的信息保存下来。通过这次实验自己亲手体会了其中加密和解密的过程,收获很大。