基于openssl的RSA加解密实现

一、引言

openssl是一套第三方的关于数据完整性的安全协议,有一些常用的密码算法,数字证书,数字签名等等方面的一些应用。由于项目需求需要用到openssl的包来实现RSA算法的加解密。

二、openssl的安装及错误解决方案

第一步,首先需要在openssl官网下载openssl包http://www.openssl.org/source/第二步,按照下载的openssl的readme文档,需要阅读install.win32文档,从读文档可知,还需要另外几个软件。

perl开发包,http://www.activestate.com/activeperl/downloads/ ,然后安装;

第三步,还需要下载masm,在微软的官方网站下载,需要visual c++ 2005,其实不用,网上有人说直接将下载的文件解压
用winrar解压缩MASMSetup.exe得到:setup.exe继续用winrar解压缩setup.exe 得到:vc_masm1.cab继续用winrar解压缩vc_masm1.cab得到:FL_ml_exe__.....  (很长的文件名,省略),将这个文件重命名为ml.exe测试得到的ml.exe , 应该显示: Microsoft (R) Macro Assembler Version 8.00.50727.104将ml.exe 拷贝到你的工作目录,即可正常使用。这里拷贝到openssl目录下。(解决异常fatal error U1077: 'ml' : return code '0x1'
D:\openssl-1.0.1e>perl Configure VC-WIN32 -DOPENSSL_USE_IPV6=0
D:\openssl-1.0.1e>ms\do_ms.bat
 
   
D:\openssl-1.0.1e>cd D:\Program Files\Microsoft Visual Studio\VC98\Bin
D:\Program Files\Microsoft Visual Studio\VC98\Bin>VCVARS32.BAT
D:\openssl-1.0.1e>nmake -f ms\ntdll.mak
Can't open perl script "util/mkdir-p.pl": No such file or directoryNMAKE : fatal error U1077: 'perl' : return code '0x2'Stop.(出现这个错误的原因是没有在openssl目录下执行此命令,转到openssl下执行就可以了)
这时,命令行会出现一行行的命令,大概要好几分钟才能执行完毕。
如果出现:fatal error U1077: 'link' : return code '0x44f'可能是版本不支持,目前还没有找到比较好的解决办法,只能降低版本试试了。
然后又出现了如下异常:fatal error U1077: 'cl' : return code '0x2'
网上说,禁用ipv6即可, perl Configure VC-WIN32 -DOPENSSL_USE_IPV6=0
继续,让它执行吧!好像是往文件夹中写什么内容!
还是报了上面的错,但是这时的out32.dll中已经有了三个文件了,但是并没有成功!
只能准备重装vc++,并且勾选上环境变量的配置
一般这种错误是由openssl的版本不同导致的,解决办法是降低openssl的版本,这里我用的openssl-0.9.7m
降低版本基本都会成功!完成后会生成三个文件夹,其中out32dll是我们编程需要的,为了方便也给加上个环境变量
在用户变量path后加上“;D:\openssl-0.9.7m\out32dll”,测试一下,进入cmd模式下,直接输入openssl如果没有出现openssl不是内部指令等之类的错误并且有相应的openssl>出现的话,说明就配置成功了!
参考文档: http://wenku.baidu.com/view/3135a4d73186bceb19e8bbf4.html
这里是安装0.9版本之后,又为visual studio 2005安装了1.0版本的,基本方法也差不多,下面是成功之后的截图:
基于openssl的RSA加解密实现_第1张图片
测试OpenSSL动态库:nmake -f ms\ntdll.mak test
  测试OpenSSL静态库:nmake -f ms\nt.mak test
  安装OpenSSL动态库:nmake -f ms\ntdll.mak install
  安装OpenSSL静态库:nmake -f ms\nt.mak install
  清除上次OpenSSL动态库的编译,以便重新编译:nmake -f ms\ntdll.mak clean
  清除上次OpenSSL静态库的编译,以便重新编译:nmake -f ms\nt.mak clean
第三步:为你的工程添加openssl的库
将openssl的inc32和openssl的out32dll两个文件都包含到工程,在vc6.0下方法如下截图

基于openssl的RSA加解密实现_第2张图片

基于openssl的RSA加解密实现_第3张图片

在visual studio 2005中类似,只需要在"项目"-"属性"-"C/C++"-"附加包含目录"中添加两个目录即可

三、编程实现

#include 
#include 

#include 
#include
#include
#include 
#include 
#include 
#include 
using namespace std;
#pragma comment(lib, "libeay32.lib")
#pragma comment(lib, "ssleay32.lib")

void generateKey() {

	/* 生成公钥 */
	RSA* rsa = RSA_generate_key( 1024, RSA_F4, NULL, NULL);
	BIO *bp = BIO_new( BIO_s_file() );
	BIO_write_filename( bp, "public.pem" );
	PEM_write_bio_RSAPublicKey(bp, rsa);
	BIO_free_all( bp );
	/* 生成私钥 */
	char passwd[]="1234";
	bp = BIO_new_file("private.pem", "w+");
	PEM_write_bio_RSAPrivateKey(bp, rsa, EVP_des_ede3(), (unsigned char*)passwd, 4, NULL, NULL);
	BIO_free_all( bp );
	RSA_free(rsa);
}

std::string bio_read_privateKey(string data) {
	OpenSSL_add_all_algorithms();
    
    BIO* bp = BIO_new( BIO_s_file() );
	
    BIO_read_filename( bp, "private.pem" );
    
    char passwd[]="1234";
    RSA* rsaK = PEM_read_bio_RSAPrivateKey( bp, NULL, NULL, passwd );
	if (NULL == rsaK) {
		perror("read key file fail!");
	}else{
		printf("read success!\n");
	}

	int nLen = RSA_size(rsaK);
	//printf("len:%d\n",nLen);
	char *pEncode = new char[nLen + 1];
	int ret = RSA_private_decrypt(data.length(),(const unsigned char*)data.c_str(),(unsigned char *)pEncode,rsaK,RSA_PKCS1_PADDING);
	std::string strRet;
	if (ret >= 0) {
		strRet = std::string(pEncode, ret);
		//printf("%s",strRet.c_str());
	}
	
	delete[] pEncode;
	CRYPTO_cleanup_all_ex_data();
	BIO_free_all( bp );
	RSA_free(rsaK);
	return strRet;
}

std::string bio_read_publicKey(string data){
	OpenSSL_add_all_algorithms();
    BIO* bp = BIO_new( BIO_s_file() );
    BIO_read_filename( bp, "public.pem" );
    RSA* rsaK = PEM_read_bio_RSAPublicKey( bp, NULL, NULL, NULL );
	if (NULL == rsaK) {
		perror("read key file fail!");
	}else{
		printf("read success!");
		int nLen = RSA_size(rsaK);
		printf("len:%d\n",nLen);
	}
	int nLen = RSA_size(rsaK);
	char *pEncode = new char[nLen + 1];
	int ret = RSA_public_encrypt(data.length(),(const unsigned char*)data.c_str(),
		(unsigned char *)pEncode,rsaK,RSA_PKCS1_PADDING);
	std::string strRet;
	if (ret >= 0) {
		strRet = std::string(pEncode, ret);
		//printf("%s\n",strRet.c_str());
	}
	delete[] pEncode;
	CRYPTO_cleanup_all_ex_data();
	BIO_free_all( bp );
	RSA_free(rsaK);
	return strRet;
}

void encryptFile(string inputfile,string outputfile){
	ifstream file(inputfile.c_str());
	ofstream outfile(outputfile.c_str());
	string tsum;
	string ss;
	while (getline(file,ss)) {
		tsum.append(ss.append("\n"));
	}
	cout<<"徐加密内容:"<


你可能感兴趣的:(密码学)