TLS编程
最近测试广州电信的电话会议平台,该平台接入采用HTTPS协议,于是有了本文。09年培训时写过一个简单的TLS C/S结构交互,采用openssl的ssl相关接口,但与生产相去胜远。本文采用openssl提供的BIO。
长链接还是短链接?
测试过程中发现长连接在一段时间内没有数据交互会被服务方释放,无法重新连接。根据自身业务选择。
BIO设置为阻塞还是非阻塞?
本场景下都为http同步请求,故设置为阻塞。代码实现时必须考虑阻塞的等待时间(测试结果是默认阻塞BIO为60s超时)对性能和业务的影响。
读写出错控制
如果写出错,需要校验BIO_should_retry,如果为true,需等待片刻后重新写,阻塞的BIO一般不会出现;
如果读出错,同样要校验BIO_should_retry,非阻塞的BIO可能会影响性能。
相关头文件:
#include <openssl/bio.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
/* Initializing OpenSSL */
SSL_library_init();
SSL_load_error_strings();
ERR_load_BIO_strings();
OpenSSL_add_all_algorithms();
SSL_CTX *m_ctx =SSL_CTX_new(SSLv23_client_method());
if (m_ctx == NULL)
{
exit(1);
}
//加载pem 该pem是openssl源码库里自带的
if(! SSL_CTX_load_verify_locations(m_ctx, "./certs/demo/ca-cert.pem", NULL))
{
exit(1);
}
下面四个函数封装了BIO的创建、释放、读和写,可以满足基本的需求了。
BIO *
bio_new ()
{
SSL *ssl;
BIO *bio = BIO_new_ssl_connect (m_ctx);
BIO_get_ssl (bio, &
ssl);
if (!ssl)
{
BIO_free_all (bio);
return NULL;
}
SSL_set_mode (ssl, SSL_MODE_AUTO_RETRY); //自动重试
BIO_set_conn_hostname (bio, "xxx.com:443");
if (BIO_do_connect (bio) & lt; = 0)
{
BIO_free_all (bio);
return NULL;
}
//校验失败是非致命的
if (SSL_get_verify_result (ssl) != X509_V_OK)
{
/* Handle the failed verification */
}
if (BIO_do_handshake (bio) & lt; = 0)
{ //ssl握手
BIO_free_all (bio);
return NULL;
}
return bio;
}
int
bio_write (BIO * bio, const char *buf, int len)
{
if (buf == NULL)
{
return PROC_FAILED;
}
if (BIO_write (bio, buf, len) & lt; = 0)
{
if (!BIO_should_retry (bio))
{
/* Handle failed write here */
return PROC_FAILED;
}
/* Do something to handle the retry */
return PROC_FAILED;
}
return PROC_SUCCESS;
}
int
bio_read (BIO * bio, char *buf, int len)
{
if (buf == NULL)
{
return PROC_FAILED;
}
int x = BIO_read (bio, buf, len);
if (x == 0)
{
/* Handle closed connection */
return PROC_FAILED;
}
else if (x & lt; 0)
{
if (!BIO_should_retry (bio))
{
/* Handle failed read here */
return PROC_FAILED;
}
/* Do something to handle the retry */
return PROC_FAILED;
}
return x;
}
int
bio_close (BIO * bio)
{
if (bio != NULL)
BIO_free_all (bio);
return PROC_SUCCESS;
}
BIO * bio = bio_new ();
if (bio == NULL)
{
return PROC_FAILED;
}
//发送数据
if (bio_write (bio, buff, strlen (buff)) == PROC_FAILED)
{
bio_close (bio);
return PROC_FAILED;
}
char response[8192] = { 0x00 };
int len = 0;
//接收数据
if ((len = bio_read (bio, response, 8192)) == PROC_FAILED)
{
bio_close (bio);
return PROC_FAILED;
}
bio_close (bio);
参考资料:
https://www.openssl.org/docs/crypto/BIO_f_ssl.html
https://www.openssl.org/docs/crypto/BIO_should_retry.html
另:BIO也很多种类型,感觉功能很强大,本人c++菜鸟,没仔细研究...
TLS编程的更多相关文章
- TLS学习总结
我们有知道 Immunity Debugger,OD 调试器,在调试程序时会设断在OEP(修改第一个字节0xcc).我在想,使用什么编程技术,代码可以在OEP前被执行.在网上找了些资料,在论坛上看到许 ...
- Apache Mina原理及典型例子分析
Apache Mina ,一个高性能 Java 异步并发网络通讯框架.利用 Mina 可以高效地完成以下任务: TCP/IP 和 UDP/IP 通讯 串口通讯 VM 间的管道通讯 SSL/TLS JX ...
- Android网络编程系列 一 JavaSecurity之JSSE(SSL/TLS)
摘要: Java Security在Java存在已久了而且它是一个非常重要且独立的版块,包含了很多的知识点,常见的有MD5,DigitalSignature等,而Android在Java Se ...
- 【windows核心编程】线程局部存储TLS
线程局部存储TLS, Thread Local Storage TLS是C/C++运行库的一部分,而非操作系统的一部分. 分为动态TSL 和 静态TLS 一.动态TLS 应用程序通过调用一组4个函数来 ...
- 异步编程系列第05章 Await究竟做了什么?
p { display: block; margin: 3px 0 0 0; } --> 写在前面 在学异步,有位园友推荐了<async in C#5.0>,没找到中文版,恰巧也想提 ...
- 浅谈 HTTPS 和 SSL/TLS 协议的背景与基础
来自:编程随想 >> 相关背景知识 要说清楚 HTTPS 协议的实现原理,至少需要如下几个背景知识. 大致了解几个基本术语(HTTPS.SSL.TLS)的含义 大致了解 HTTP 和 ...
- TLS 与 python thread local
TLS 先说TLS( Thread Local Storage),wiki上是这么解释的: Thread-local storage (TLS) is a computer programming m ...
- 牛人整理分享的面试知识:操作系统、计算机网络、设计模式、Linux编程,数据结构总结 转载
基础篇:操作系统.计算机网络.设计模式 一:操作系统 1. 进程的有哪几种状态,状态转换图,及导致转换的事件. 2. 进程与线程的区别. 3. 进程通信的几种方式. 4. 线程同步几种方式.(一定要会 ...
- Node.js高级编程读书笔记Outline
Motivation 世俗一把,看看前端的JavaScript究竟能做什么. 顺便检验一下自己的学习能力. Audience 想看偏后台的Java程序员关于前端JavaScript的认识的职业前端工程 ...
随机推荐
- 深入浅出php socket编程
对TCP/IP.UDP.Socket编程这些词你不会很陌生吧?随着网络技术的发展,这些词充斥着我们的耳朵.那么我想问: 1.什么是TCP/IP.UDP?2.Socket在哪里呢?3.Socket是什么 ...
- python heapq模块使用
Python内置的heapq模块 Python3.4版本中heapq包含了几个有用的方法: heapq.heappush(heap,item):将item,推入heap >>> it ...
- https 不会被中间人攻击——因为中间人即使拿到了数据,也是加密的
只要你登陆了一个使用 HTTPS 数据加密的网站,浏览的页面的内容如果被人中途看见,将会是一团乱码.它也能保证,你浏览的页面就是你想浏览的,不会被黑客在中途修改,网站收到的数据包也是你最初发的那个,不 ...
- “SecureCRT遇到一个致命的错误且必须关闭”处理办法
打开SecureCRT时报错:SecureCRT遇到一个致命的错误且发须关闭.一个崩溃转储文件已创建于... 解决办法是,如下在cmd中输入regedit回车打开注册表编缉器 展开HKEY_LOCAL ...
- Oracle使用expdp/impdp导出导入数据
这里假设已存在数据库用户,并是计划通过该用户导入导出该用户表空间上的数据.(我们这里假定用户名称为ls) 1.创建逻辑目录(数据库命令,sqlplus中执行) Oracle不能直接指定系统目录让他去读 ...
- js中对象如何添加新属性?
假如登陆需要用户.密码.是否记住密码,那么怎么定义一个对象保存这些信息 1)方法1:声明动态对象 添加属性 //创建obj对象 var obj = new Object(); //为对象添加动态属性 ...
- Echarts dataZoom缩放功能参数详解:
dataZoom=[ //区域缩放 { id: 'dataZoomX', show:true, //是否显示 组件.如果设置为 false,不会显示,但是数据过滤的功能还存在. backgroundC ...
- 深入理解 Java 虚拟机——走近 Java
1.1 - 概述 Java 总述:Java 不仅是一门编程语言,还是一个由一系列 计算机软件 和 规范 形成的技术体系,这个技术体系提供了完整的用于软件开发和跨平台部署的支持环境,并广泛应用于 嵌入式 ...
- Docker容器使用jenkins部署web项目--总结(二)
(1)需要安装Docker容器,在Docker容器内安装jenkins,gogs,tomcat. 新建maven项目,添加findbugs plugin. 使用docker启动jenkins,go ...
- information_schema
views 视图表,查看当前数据库有哪些视图 select table_catalog,table_schema,table_name,is_updatable,definer,security_ty ...