使用OpenSSL API 建立SSL安全通信的一般流程

来源:互联网 发布:givens变换例题矩阵论 编辑:程序博客网 时间:2024/05/16 23:43

使用OpenSSL API 建立SSL安全通信的一般流程

OpenSSL是一套开放源代码的SSL套件,其函数库是以C语言所写成,实现了基本的传输层数据加密功能。此软件是以两个加拿大人Eric A. Young 和Tim J. Hudson所写的SSLeay为基础所发展的,SSLeay随着两人前往RSA公司任职而停止开发。1998年,OpenSSL项目组接管了OpenSSL的开发工作,并推出了OpenSSL的0.9.1版,到目前为止,OpenSSL的算法已经非常完善,对SSL2.0、SSL3.0以及TLS1.0都支持。

    OpenSSL同时实现了客户端与服务器的开发接口,使用OpenSSL进行安全通信的大致流程如下图所示。


图1 使用OpenSSL API建立SSL通信的流程

一、OpenSSL API

【本小节内容改自:秀秀的新浪博文《SSL协议的分析及实现-2》】

    SSL通信模型采用标准的C/S结构,因此基于OpenSSL的程序可以被分为两个部分:Client和Server。上图1是建立SSL通信的流程简图,说明了基于OpenSSL的程序所要遵循的以下几个重要步骤:

(1)OpenSSL初始化

    OpenSSL在使用之前,必须进行相应的初始化工作。完成初始化功能的函数原型为:

?
1
2
voidSSL_load_error_strings(void);// 错误信息的初始化  
intSSL_library_int(void);// 初始化SSL算法库函数( 加载要用到的算法 ),调用SSL函数之前必须调用此函数
    在建立SSL连接之前,要为Client和Server分别指定本次连接采用的协议及其版本,目前能够使用的协议版本包括SSLv2、SSLv3、SSLv2/v3和TLSv1.0。SSL连接若要正常建立,则要求Client和Server必须使用相互兼容的协议。

(2)创建CTX

    在OpenSSL中,CTX是指SSL会话环境。建立连接时使用不同的协议,其CTX也不一样。创建CTX的过程中会依次用到以下OpenSSL函数:

?
1
2
3
4
5
6
7
8
9
10
//客户端、服务端都需要调用的  
SSL_CTX_new()        //申请SSL会话环境  
//若有验证对方证书的需求,则需调用  
SSL_CTX_set_verify()           //指定证书验证方式  
SSL_CTX_load_verify_location() //为SSL会话环境加载本应用所信任的CA证书列表  
//若有加载证书的需求,则需调用  
SSL_CTX_use_certificate_file()      //为SSL会话加载本应用的证书  
SSL_CTX_use_certificate_chain_file()//为SSL会话加载本应用的证书所属的证书链  
SSL_CTX_use_PrivateKey_file()       //为SSL会话加载本应用的私钥  
SSL_CTX_check_private_key()         //验证所加载的私钥和证书是否相匹配

(3)建立SSL套接字

    在此之前要先创建普通的流套接字,完成TCP三次握手,建立普通的TCP连接。然后创建SSL套接字,并将之与流套接字绑定。这一过程中会使用以下几个函数:

?
1
2
3
4
SSL *SSl_new(SSL_CTX *ctx);  //申请一个SSL套接字
intSSL_set_fd(SSL *ssl,intfd);   //绑定读写套接字
intSSL_set_rfd(SSL *ssl,intfd);  //绑定只读套接字
intSSL_set_wfd(SSL *ssl,intfd);  //绑定只写套接字

(4)完成SSL握手

    在这一步,我们需要在普通TCP连接的基础上,建立SSL连接。与普通流套接字建立连接的过程类似:Client使用函数SSL_connect()【类似于流套接字中用的connect()】发起握手,而Server使用函数SSL_ 
accept()【类似于流套接字中用的accept()】对握手进行响应,从而完成握手过程。两函数原型如下:

?
1
2
intSSL_connect(SSL *ssl);
intSSL_accept(SSL *ssl);

    握手过程完成之后,Client通常会要求Server发送证书信息,以便对Server进行鉴别。其实现会用到以下两个函数:

?
1
2
X509 *SSL_get_peer_certificate(SSL *ssl);  //从SSL套接字中获取对方的证书信息
X509_NAME *X509_get_subject_name(X509 *a); //得到证书所用者的名字

(6)进行数据传输

    经过前面的一系列过程后,就可以进行安全的数据传输了。在数据传输阶段,需要使用SSL_read( )和SSL_write( )来代替普通流套接字所使用的read( )和write( )函数,以此完成对SSL套接字的读写操作,两个新函数的原型分别如下:

?
1
2
intSSL_read(SSL *ssl,void*buf,intnum);            //从SSL套接字读取数据
intSSL_write(SSL *ssl,constvoid *buf,intnum);     //向SSL套接字写入数据

(7)会话结束

    当Client和Server之间的通信过程完成后,就使用以下函数来释放前面过程中申请的SSL资源:

?
1
2
3
intSSL_shutdown(SSL *ssl);       //关闭SSL套接字
voidSSl_free(SSL *ssl);          //释放SSL套接字
voidSSL_CTX_free(SSL_CTX *ctx);  //释放SSL会话环境

 

二、简介与概述

    OpenSSL是一个开源的代码库,它所实现的所有SSL相关功能都可以在C、C++语言中直接使用。OpenSSL具有以下优点[16]:

  • 采用C语言开发,支持多种操作系统,可移植性好;
  • 功能全面,支持大部分主流密码算法、相关标准协议和SSL协议;
  • 开放源代码,应用者能很好地了解算法实现过程;
  • 具备应用程序(即OpenSSL指令),既可以直接使用,也可以进行二次开发;
  • 免费使用,能够用于商业和非商业。

    OpenSSL整个软件包主要分为三个部分:密码算法库、SSL协议库以及应用程序。其中,密码算法库是OpenSSL的核心,SSL协议库是在密码算法库的基础上对SSL协议的实现,应用程序是直接使用OpenSSL各种功能的接口,包括密码算法相关功能与SSL协议相关功能。这三个部分的关系如图2.1所示。


图2.1 OpenSSL套件各组成部分的关系

密码算法库

    OpenSSL的密码算法库实现了大部分主流密码算法,包括对称密码算法(AES算法、DES算法、Blowfish算法、CAST算法、IDEA算法、RC2算法、RC5算法与RC4算法)、非对称密码算法(DH算法、RSA算法、DSA算法与EC算法)和信息摘要算法(MD2算法、MD5算法、MDC2算法、SHA算法、SHA1算法和RIPEMD算法),并提供了对数字证书和密钥的管理接口。

SSL协议库

    OpenSSL的SSL协议库实现了SSL 2.0、SSL 3.0和TLS 1.0。该库提供了丰富的API函数,这些API函数将SSL协议的处理细节进行了完美的封装。当使用SSL协议库进行SSL应用程序开发时,不需要关心如何交换SSL握手消息,如何使用会话密钥加解密通信数据等细节问题,而只需考虑如何实现程序的实际功能。

应用程序

    OpenSSL的应用程序是基于OpenSSL的密码算法库和SSL协议库写成的,它已经成为了OpenSSL重要的一个组成部分。通过调用OpenSSL的相应指令,可以使用密钥生成、证书管理、格式转换、数据加密和签名、SSL测试以及其它辅助配置功能。

0 0
原创粉丝点击