基于OpenSSL的PKI文件传输系统的设计与实现

时间:2022-07-08 01:29:59

基于OpenSSL的PKI文件传输系统的设计与实现

摘要: 针对互联网用户所面临的安全问题 ,利用OpenSSL软件设计并实现一个通用的文件传输系统。该系统具备通信双方文件的加密传输,数字签名和认证功能,从而能保证文件传递的安全需求。

关键词: 公钥基础设施;数字签名;文件加密;认证

中图分类号:TP393 文献标识码:A 文章编号:1009-3044(2014)25-5866-03

近年来,电子商务、网上银行等Web应用得到了广泛的发展,互联网的安全问题越来越引起人们的重视。为了给用户提供安全的网络服务,互联网必须提供机密性、身份鉴别、完整性、非否认功能。PKI(Public Key Infrastructure)中文全称为公钥基础设施,是当下被广泛采用互联网安全解决方案。它是一个以公钥技术为基础的,提供和实施安全服务的具有普适性的安全基础设施,使用户可以在多种应用环境下方便地使用加密和数字签名技术,为诸如电子商务、网上银行和网上证券等各种具体应用提供可靠的安全服务。[1,2,3]本文利用开源的OpenSSL软件开发包设计和实现了PKI文件传输系统,实现的具体功能有:通信双方文件的加密传输、数字签名和认证。

1 文件传输系统的设计

带加密和签名的文件传送过程如下:若A方为发送方,B方为接收方。A方的主要工作是:(1)将明文通过hash 变换成hash值;(2)A用自己的私钥将hash值签名,得到签名的hash值;(3)用随机生成的会话密钥将明文进行对称加密;(4)用B的公钥对会话密钥和签名的hash值进行非对称加密。经过A方的工作要发送的文件转换成包含文件密文、签名、和会话密钥密文的文件在互联网上传递。B方的主要工作是:(1) 对文件密文进行对称解密,对签名和会话密钥密文进行非对称解密; (2)用自己的私钥解密加密的签名和会话密钥; (3)用会话密钥对密文进行解密从而得到明文; (4)用A 的公钥解密签名后验证。

2 文件传输系统的实现步骤

根据图1所示的文件传输过程,设计的文件传输系统通过如下4个步骤实现:

1)获取证书。首先要得到根CA的证书Root.cer和证书A.cer和B.cer。证书A.cer是发送方A的证书, B.cer是接收方B的证书。

2) 验证证书并导出私钥。利用A、B的证书可分别导出A、B的私钥A.pfx和B.pfx。A和B在进行文件传送前分别得到对方证书,验证对方证书的有效性,并获取自己的私钥。

3) 发送方加密和签名文件。发送方A先用自己的私钥将明文通过hash变换得到的hash值进行加密后签名,并用随机生成的会话密钥将明文对称加密得到密文,再用接收方B的公钥将会话密钥和签名hash值非对称加密,将得到的密文和用B的公钥加密的签名和会话密钥作为发送数据存放。

4)接收方解密和验证文件。接收方B先用自己的私钥将加密的签名和会话密钥解密,再用会话密钥将密文对称解密得到明文,最后用发送方A的公钥解密签名,并进行验证。

目前我国几乎每个行业都有自己的CA认证系统,用户只要登陆需要认证的电子商务网站,注册并按要求填写完毕申请者的信息,网站认证中心核实后,就会取得认证证书的系列码和证书秘钥。[4,5]所以步骤一在此省略,下面重点介绍二、三、四步骤的实现。

3 文件传输系统的核心代码

系统使用C++语言开发,程序在VC++6.0下调试通过。

3.1发送方核心代码

1)CA产生的证书和私钥的格式分别是.cer和加密的.pfx文件,这两种文件要分别转换成X509和PKCS12的结构体才能在openssl中调用函数读取。私钥格式转换关键代码:

//把Pfx文件转化为PKCS12结构体

bio = BIO_new(BIO_s_mem());

rv = BIO_write(bio,PfxBuf,PfxBufLen);

pfx = d2i_PKCS12_bio(bio, NULL);

2) 发送方A用自己的私钥将明文(在a.txt存储)hash变换得到的hash值加密得到签名hash值。以下是签名关键代码:

//打开待发送的文件,不断循环,以4096字节为单位读取文件,并签名

for(;;)

{

BufferLen=fread(Buffer,1,4096,fp);//每次读取4096个字节

if(!EVP_SignUpdate(&mdctx, Buffer, BufferLen))//签名

{

EVP_PKEY_free(pkey);

X509_free(SignCert);

X509_free(RecvCert);

PKCS12_free(pfx);

}

}

3) 随机产生会话密钥,以下是随机产生会话密钥的代码:

//产生随机数,作为会话密钥

RAND_bytes(SessionKey,16);

4)用随机生成的会话密钥将明文对称加密得到密文,以下是加密关键代码:

//利用回话密钥加密原文,并输出到密文到文件

fpIn = fopen(sSrcFile,"rb");

fpOut = fopen(sDesFile,"wb");

5) 接收方B的公钥将会话密钥和签名值分别非对称加密,以下是非对称加密的关键代码:

//使用接收者证书公钥加密签名

CipherSignLen= EVP_PKEY_encrypt(CipherSign,Sign,100,

X509_get_pubkey(RecvCert));

for(ki=0; ki

SessionKey[16+ki]=Sign[100+ki];

}

//使用接收者证书公钥加密会话密钥

CipherSessionKeyLen= EVP_PKEY_encrypt(CipherSessionKey,SessionKey,44,

X509_get_pubkey(RecvCert));

3.2接收方核心代码

1)用接收方B的私钥将加密的会话密钥和加密的签名分别解密,得到会话密钥和签名。 以下是解密加密的密会话密钥和加密的签名的关键代码:

//接收者私钥解签名

SignLen = EVP_PKEY_decrypt(Sign,CipherSign,CipherSignLen,pkey);

//接收者私钥解密会话密钥

SessionKeyLen= EVP_PKEY_decrypt(SessionKey,CipherSessionKey,

CipherSessionKeyLen,pkey);

for(ki=0; ki

Sign[100+ki]=SessionKey[16+ki];

}

SignLen+=28;

2) 利用解密出来的会话密钥解密发方文件(b.txt)中的会话密钥密文,并把解密出来的明文文存放在(c.txt)。以下是解密密文的关键代码:

//利用明文的会话密钥解密安全报文

EVP_CIPHER_CTX_init(&ctx);

fpOut = fopen(sOutFile,"wb");

//设置解密算法和密钥。

rv=EVP_DecryptInit_ex(&ctx,EVP_get_cipherbynid(NID_aes_128_ecb),NULL,SessionKey,NULL);

//以1024字节为单位,循环读取安全报文,解密并保存到文件。

for(;;)

{

inl = fread(in,1,1024,fp);//读取1024个字节

rv = EVP_DecryptUpdate(&ctx,out,&outl,in,inl);//解密

fwrite(out,1,outl,fpOut);//保存到文件

}

rv = EVP_DecryptFinal_ex(&ctx,out,&outl);//完成解密,输出剩余的明文。

fwrite(out,1,outl,fpOut);

3) 验证发方A的签名是否正确。以下是验证A签名的关键代码:

//验证签名

if(!EVP_VerifyFinal(&mdctx,Sign,SignLen,X509_get_pubkey(SignCert)))

{

X509_free(SignCert);

EVP_MD_CTX_cleanup(&mdctx);

}

4 文件传输系统测试

测试是在a.txt中存储发送的明文信息:123456。在b.txt存储的是加密后的密文和用接收方B的公钥加密的签名以及会话密钥。c.txt用来存储的内容是接收方B先用自己的私钥将加密的签名和会话密钥解密,再用会话密钥将密文对称解密得到明文。从运行的结果看a.txt与c.txt的内容一致,即文件加密传输后经解密与源文件内容一致。

5 结束语

本文详细地叙述了基于opensslpki文件传输系统设计实现。该系统具有较强的通用性,稍作修改即可作为具体应用系统的子功能,有较高的应用价值。

参考文献:

[1] Carlisle Adams,Steve Lloyd.公开密钥基础设施―概念、标准和实施[M].北京:人民邮电出版社,2001:3-50.

[2] 肖凌,李之棠.公开密钥基础设施[J].计算机工程与应用,2002(10):137-139.

[3] 潘雨相.基于PKI技术的电子商务安全支付系统设计[J].现代电子技术,2014,37(12) : 93-95.

[4] 邵丽.我国CA认证的发展探讨[J].中国商贸,2010(4):81-82.

[5] 孙洁,辛明.我国CA认证行业现状浅析[J].光盘技术,2007(4):10-12.

上一篇:浅谈VSWR对民航甚高频通信系统的影响 下一篇:对网络中心机房建设与维护的探讨