美文网首页
基于openssl的https协议(tcp)主要接口汇总

基于openssl的https协议(tcp)主要接口汇总

作者: starmier | 来源:发表于2019-09-17 17:10 被阅读0次

    1. HTTPS 简述

    HTTPS是以安全为目标的HTTP通道,简单讲是HTTP的安全版。即HTTP下加入SSL层,HTTPS的安全基础是SSL,因此加密的详细内容就需要SSL。HTTPS通信是在TCP通信层与HTTP应用层之间增加了SSL层,如果应用层不是HTTP协议也是可以使用SSL加密通信的,比如WebSocket协议WS的加上SSL层之后的WSS(https=http+ssl)。


    image.png

    Socket连接建立后的SSL连接建立过程:


    image.png

    2. OpenSSL的主要API

    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进行安全通信的大致流程如下图所示。
    
    image.png

    OpenSSL的API很多,但并不是都会被使用到,如果需要查看某个API的详细使用方法可以阅读API文档
    OpenSSL在使用之前,必须进行相应的初始化工作。在建立SSL连接之前,要为Client和Server分别指定本次连接采用的协议及其版本,目前能够使用的协议版本包括SSLv2、SSLv3、SSLv2/v3和TLSv1.0。SSL连接若要正常建立,则要求Client和Server必须使用相互兼容的协议。CTX是SSL会话环境,建立连接时使用不同的协议,其CTX也不一样。主要使用的为文件ssl.h中的接口。

    2.1. init ssl & create socket

    2.1.1. Register the error strings for libcrypto & libssl

    # if OPENSSL_API_COMPAT < 0x10100000L
    #  define SSL_load_error_strings() \
        OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS \
                         | OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL)
    # endif
    

    2.1.2. Register the available ciphers and digests

    # if OPENSSL_API_COMPAT < 0x10100000L
    #  define SSL_library_init() OPENSSL_init_ssl(0, NULL)
    # endif
    

    2.1.3. New context saying we are a client, and using SSL 2 or 3

    __owur SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth);//申请SSL会话环境,客户端、服务端都需要调用
    
    //若有验证对方证书的需求,则需调用
    void SSL_CTX_set_verify(SSL_CTX *ctx, int mode, SSL_verify_cb callback);//指定证书验证方式
    __owur int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile,
                                             const char *CApath);//为SSL会话环境加载本应用所信任的CA证书列表
    
    //若有加载证书的需求,则需调用
    __owur int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file,
                                            int type);//为SSL会话加载本应用的证书
    /* PEM type */
    __owur int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file);//为SSL会话加载本应用的证书所属的证书链
    
    __owur int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file,
                                           int type);//为SSL会话加载本应用的私钥
    __owur int SSL_CTX_check_private_key(const SSL_CTX *ctx);//验证所加载的私钥和证书是否相匹配
    

    2.1.4. Create an SSL struct for the connection with SSL_CTX

    
    SSL *SSL_new(SSL_CTX *ctx);//创建一个SSL套接字,在创建SSL套接字之前要先创建Socket套接字,建立TCP连接。
    
    # ifndef OPENSSL_NO_SOCK
    __owur int SSL_set_fd(SSL *s, int fd);//以读写模式绑定流套接字
    __owur int SSL_set_rfd(SSL *s, int fd);//以只读模式绑定流套接字
    __owur int SSL_set_wfd(SSL *s, int fd);//以只写模式绑定流套接字
    # endif
    

    2.2. SSL handshake

    2.2.1. Initiate SSL handshake, after ::connect

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

    //int     connect(int, const struct sockaddr *, socklen_t) __DARWIN_ALIAS_C(connect);
    
    __owur int SSL_connect(SSL *ssl);
    __owur int SSL_accept(SSL *ssl);
    

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

    # ifdef HEADER_X509_H
    __owur X509 *SSL_get_peer_certificate(const SSL *s);////从SSL套接字中获取对方的证书信息
    # endif
    
    X509_NAME *X509_get_subject_name(const X509 *a);////得到证书所用者的名字,所在头文件x509.h
    

    2.3. read/write

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

    __owur int SSL_read(SSL *ssl, void *buf, int num);//从SSL套接字读取数据
    __owur int SSL_write(SSL *ssl, const void *buf, int num);//向SSL套接字写入数据
    

    2.4. Disconnect & free connection struct

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

    int SSL_shutdown(SSL *s);//关闭SSL套接字
    void SSL_free(SSL *ssl);//释放SSL套接字
    void SSL_CTX_free(SSL_CTX *);//释放SSL会话环境
    

    3. SSL 和 TLS

    HTTPS 使用 SSL(Secure Socket Layer) 和 TLS(Transport LayerSecurity)这两个协议。
    SSL 技术最初是由浏览器开发商网景通信公司率先倡导的,开发过 SSL3.0之前的版本。目前主导权已转移到 IETF(Internet Engineering Task Force,Internet 工程任务组)的手中。

    IETF 以 SSL3.0 为基准,后又制定了 TLS1.0、TLS1.1 和 TLS1.2。TSL 是以SSL 为原型开发的协议,有时会统一称该协议为 SSL。当前主流的版本是SSL3.0 和 TLS1.0。

    由于 SSL1.0 协议在设计之初被发现出了问题,就没有实际投入使用。SSL2.0 也被发现存在问题,所以很多浏览器直接废除了该协议版本。

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

    HTTPs握手流程抓包解析

    https://blog.csdn.net/howeverpf/article/details/18993945

    基于OpenSSL的HTTPS通信C++实现

    基于openssl的https client例子

    相关文章

      网友评论

          本文标题:基于openssl的https协议(tcp)主要接口汇总

          本文链接:https://www.haomeiwen.com/subject/lmobdctx.html