C++ windows客户端支持SSL双向认证
C++ windows客户端支持SSL双向认证,服务端是JAVA开发的,使用的证书是jks格式的。C++并不支持JKS格式的证书,所以要用openssl进行转换下。
1、 需要先把jks转成.p12文件
keytool -importkeystore -srckeystore demo.jks -destkeystore demo.p12 -srcstoretype jks -deststoretype pkcs12
2、然后把.p12文件转成pem文件
openssl pkcs12 -nodes -in demo.p12 -out demo.pem
3、拷贝-----BEGIN CERTIFICATE-----
-----END CERTIFICATE-----到cacert.pem文件里
如果有cer格式证书文件有可用下面的命令直接转成cacert.pem
openssl x509 -inform der -in demo.cer -out cacert.pem
4、提取私有key
openssl pkcs12 -in demo.p12 -nocerts -nodes -out demo.key;
openssl rsa -in demo.key -out privkey.pem;
流程图:

有几点注意的地方:
1、SSL_load_error_strings();
SSL_library_init();
OpenSSL_add_all_algorithms();
只需要执行一次即可,即使后面需要重新连接,也不需要再次调用。所以放在构造函数里可以里了。
2、一般连接的时候,都会把socket设置成非阻塞的,防止服务端不在线,需要连接很久。但是设置非阻塞之后,ssl_connect可能会连接失败,所以需要多次连接。
所以我自己封装了下:
int CSslSocketClient::SSL_ShakeHands()
{
int ssl_conn_ret = SSL_connect(m_ssl);
if (ssl_conn_ret == )
{
return ;
}
else if (ssl_conn_ret == -)
{
int ssl_conn_err = SSL_get_error(m_ssl, ssl_conn_ret);
if (SSL_ERROR_WANT_READ == ssl_conn_err ||
SSL_ERROR_WANT_WRITE == ssl_conn_err) {
//需要再次来进行握手
return -;
}
else
{
return -;
}
}
else
{
return -;
}
}
外面调用的时候,如果返回值是0,说明成功,如果是-1,说明失败,如果是-2,说明需要再次ssl连接。
3、因为要支持双向认证,所以在SSL_new之前需要加载下证书,并check下。
CString strPath;
strPath.Format("%s\\pem\\%s", m_strWorkPath, CERT_NAME);
if (SSL_CTX_use_certificate_file(m_ctx, strPath, SSL_FILETYPE_PEM) <= ){
MYTRACE("CSslSocketClient", "certificate file error!");
DisconnectSocket();
return -;
} strPath.Format("%s\\pem\\%s", m_strWorkPath, PRIV_NAME);
if (SSL_CTX_use_PrivateKey_file(m_ctx, strPath, SSL_FILETYPE_PEM) <= ){
MYTRACE("CSslSocketClient", "use privatekey file Error: %s\n", ERR_reason_error_string(ERR_get_error()));
DisconnectSocket();
return -;
}
if (!SSL_CTX_check_private_key(m_ctx)){
MYTRACE("CSslSocketClient", "Check private key failed!\n");
DisconnectSocket();
return -;
}
4、类的析构函数里释放内存ssl的内存,但是仍然会有2MB左右的内存泄漏,不会也没有关系,反正这时候程序已经退出了。
// 释放内存
sk_SSL_COMP_free(SSL_COMP_get_compression_methods());
CRYPTO_cleanup_all_ex_data(); ERR_remove_state();
CONF_modules_unload();
CONF_modules_free();
ERR_free_strings();
ERR_remove_thread_state(NULL);
EVP_cleanup();
上面的函数需要头文件
#include <openssl/err.h>
#include <openssl/conf.h>
C++ windows客户端支持SSL双向认证的更多相关文章
- nginx支持ssl双向认证配置
nginx支持ssl双向认证配置 listen 443; server_name test.com; ssl on; ssl_certificate server.crt; //server端公钥 s ...
- SSL握手通信详解及linux下c/c++ SSL Socket代码举例(另附SSL双向认证客户端代码)
SSL握手通信详解及linux下c/c++ SSL Socket代码举例(另附SSL双向认证客户端代码) 摘自: https://blog.csdn.net/sjin_1314/article/det ...
- SSL双向认证(高清版)
介绍了SSL双向认证的一些基本问题,以及使用Nginx+PHP基于它搭建https的Webservice. 之前的方式只是实现1:1的模式,昨天同事继续实现了n:1的模式,这里我再整理记录下. 由于n ...
- Nginx、SSL双向认证、PHP、SOAP、Webservice、https
本文是1:1模式,N:1模式请参见新的一篇博客<SSL双向认证(高清版)> ----------------------------------------------------- 我是 ...
- apache用户认证,ssl双向认证配置
安装环境: OS:contos 6.4 httpd:httpd-2.2.15-59.el6.centos.i686.rpm openssl:openssl-1.0.1e-57.el6.i686.rpm ...
- SSL双向认证和SSL单向认证的流程和区别
refs: SSL双向认证和SSL单向认证的区别https://www.jianshu.com/p/fb5fe0165ef2 图解 https 单向认证和双向认证!https://cloud.tenc ...
- php实现https(tls/ssl)双向认证
php实现https(tls/ssl)双向认证 通常情况下,在部署https的时候,是基于ssl单向认证的,也就是说只要客户端认证服务器,而服务器不需要认证客户端. 但在一些安全性较高的场景,如银行, ...
- php使用curl库进行ssl双向认证
官方文档: http://www.php.net/manual/zh/function.curl-setopt.php#10692 官方举例: <?phpcurl_setopt($ch, CUR ...
- tomcat配置SSL双向认证
一.SSL简单介绍 SSL(Secure Sockets Layer 安全套接层)就是一种协议(规范),用于保障客户端和服务器端通信的安全,以免通信时传输的信息被窃取或者修改. 怎样保障数据传输安全? ...
随机推荐
- Linux 下的mysql+centos7+主从复制
mysql+centos7+主从复制 MYSQL(mariadb) MariaDB数据库管理系统是MySQL的一个分支,主要由开源社区在维护,采用GPL授权许可.开发这个分支的原因之一是:甲骨文公 ...
- homestead 重复出错
vboxmanage list vms "homestead-7" {2c8b0ea2-d862-4f4e-bcb2-2d7db848686f} vboxmanage unregi ...
- 2019-6-23-WPF-网络-request-的-read-方法不会返回
title author date CreateTime categories WPF 网络 request 的 read 方法不会返回 lindexi 2019-06-23 11:26:26 +08 ...
- python 文件读写编码
- Gym - 101962K _ Rei do Cangaço
题意:给予n个房间,每个房间可以的到x个金币(x可能为负数),可以进行两种操作: 右移3i个房间,并且打开除最后一个的所有房间,如在1号房间,第一次移动可以移动到4号,并且打开1,2,3三个房间. 只 ...
- 【git基本操作】总结
"git fetch GitLab: Your account has been blocked.fatal: Could not read from remote repository. ...
- 从零学React Native之08Image组件
开发过程中, 几乎每个项目都会用到图片. RN就是通过Image组件显示图片.既可以加载网络图片,也可以加载本地资源图片. Image组件必须在样式中声明图片的款和高.如果没有声明,则图片将不会被呈现 ...
- Codeforces 662D International Olympiad【贪心】
比赛的时候后缀长度在4位以内的时候分类讨论了一下,其实他们完全是一个套路的..并不需要讨论. 然后没有考虑前导0的情况,就wa了.. 题目链接: http://codeforces.com/probl ...
- Knative 初体验:Eventing Hello World
作者 | 阿里云智能事业群高级开发工程师 元毅 基于事件驱动是Serveless的核心功能之一,通过事件驱动服务,满足了用户按需付费(Pay-as-you-go)的需求.在之前的文章中我们介绍过 Kn ...
- 4818 Largest Empty Circle on a Segment (几何+二分)
ACM-ICPC Live Archive 挺水的一道题,直接二分圆的半径即可.1y~ 类似于以前半平面交求核的做法,假设半径已经知道,我们只需要求出线段周围哪些位置是不能放置圆心的即可.这样就转换为 ...