实验目的:
1.熟悉openssl安装和API使用
2.理解aes加密算法原理
试验环境:
Visual Studio 2010
openssl-0.9.8zg
实验内容及过程:
1.配置openssl
(1)官网http://www.openssl.org/source/下载openssl,并解压。
(2)下载perl并安装ActivePerl。在Windows下编译OpenSSL需要使用Perl脚本调用Configure产生MakeFile文件。在http://www.activestate.com/activeperl下下载针对Windows的版本。
(3)运行“cmd”命令,在控制台窗口,使用“cd”命令改变当前目录为openssl-1.0.1e源码所在目录。
(4)执行Configure。运行“perl Configure VC-WIN32 --prefix=c:/openssl-1.0.1e”。prefix参数的意义是OpenSSL编译好后的安装路径(64位openssl使用:perl Configure VC-WIN64A)。
(5)运行“ms\do_ms”。
(6) 运行“nmake -f ms\ntdll.mak”。执行make进行编译。
(7)运行“nmake -f ms\ntdll.mak install”,将安装编译后的OpenSSL复制到指定目录。会看到有三个文件夹:bin、include、lib。
(8)在VS中配置openssl路径。
2.VS下编程
AES_KEYaeskey;//定义密匙
设置加密密匙函数:
intAES_set_encrypt_key(const unsigned char *userKey, const int bits,AES_KEY *key);
设置解密密匙函数:
intAES_set_decrypt_key(const unsigned char *userKey, const int bits, AES_KEY*key);
加密函数:
voidAES_encrypt(const unsigned char *in, unsigned char *out,const AES_KEY *key);
解密函数:
voidAES_decrypt(const unsigned char *in, unsigned char *out,const AES_KEY *key);
代码:
#include <memory.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
#include <openssl/aes.h>
#pragma comment(lib,"libeay32.lib")
char enString[10000];//加密后
char deString[10000];//解密后
//加密函数
void enAes(char inString[], int inLen, char passwd[], int pwdLen,char add[])
{
int i,j, len, nLoop, nRes;
FILE * f2=fopen(add,"wb");//写入加密文件
cout <<"加密结果:"<<endl;
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];
fprintf(f2,"%c",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];
fprintf(f2,"%c",buf2[j]);
}
}
enString[i*16+j]=0;
fclose(f2);
cout << enString<<endl;//显示加密结果
}
//解密函数
void deAes(char inString[], int inLen, char passwd[], int pwdLen,char add[])
{
int i,j, len, nLoop, nRes;
FILE * f22=fopen(add,"wb");//写入解密文件
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_decrypt_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_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]=inString[i*16+j];
AES_decrypt(buf,buf2,&aeskey);
for(j=0;j<16;j++) {
deString[i*16+j]=buf2[j];
}
}
deString[i*16+nRes]=0;
fprintf(f22,"%s",deString);
fclose(f22);
cout << "解密结果:"<<endl<<deString <<endl; //显示解密结果
}
int main(int argc, char* argv[])
{
while(true){
char mode[10];
char add[20];
char inString[10000];
char passwd[50];
cout <<"加密(enc) 解密(dec):"<<endl;
cin.getline(mode,10);
cout <<"文件地址(例:d:/123.txt):"<<endl;
cin.getline(add,20);
cout << "密码:"<<endl;
cin.getline(passwd,50);
cout<<endl;
if(strcmp(mode,"enc")==0){
FILE * f1=fopen(add,"rb");
char tmp;
int i=0;
while(!feof(f1)){
tmp=fgetc(f1);
inString[i++]=tmp;
}
inString[i]=0;
fclose(f1);
enAes(inString, i, passwd, strlen(passwd),add);
cout<<endl;
}
else if(strcmp(mode,"dec")==0){
FILE * f11=fopen(add,"rb");
char tmp;
int i=0;
while(!feof(f11)){
tmp=fgetc(f11);
inString[i++]=tmp;
}
inString[i]=0;
fclose(f11);
deAes(inString, i, passwd, strlen(passwd),add);
cout<<endl;
}
}
return 0;
}