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

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例子

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,734评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,931评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,133评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,532评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,585评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,462评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,262评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,153评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,587评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,792评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,919评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,635评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,237评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,855评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,983评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,048评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,864评论 2 354

推荐阅读更多精彩内容