【计算机网络】网络安全 : 运输层安全协议 ( 安全套接字层 SSL | 运输层安全 TSL | SSL 服务 | SSL 安全会话建立流程 )
文章目录一、运输层安全协议二、运输层使用 SSL 前后对比三、SSL 与 TSL 对比四、SSL 服务五、SSL 安全会话建立过程一、运输层安全协议运输层安全协议 :① 安全套接字层 ( SSL , Secure Socket Layer ) :作用位置 : 端系统 应用层 HTTP 与 运输层 之间 ;TCP 安全 : 在 TCP 基础上建立安全通道 , 为 TCP 传输提供安全服务 ;WEB 安全标准 : SSL 3.0② 运输层安全 ( TSL , Transport Layer Security ) :基础 : 基于 SSL 3.0 ;作用 : 为 基于 TCP 协议的应用提供安全服务 ;二、运输层使用 SSL 前后对比运输层使用 SSL 前后对比 :① SSL 使用情况 : SSL 增强了 TCP 服务 , SSL 是运输层协议 , 但其需要使用安全运输程序 , 其实际被分在应用层 ;② 普通 TCP 通信 : 应用程序 ( 应用层 ) -> TCP 套接字 -> TCP 协议 ( 运输层 )③ SSL TCP 通信 : 应用程序 ( 应用层 ) -> SSL 套接字 -> SSL 子层 ( 应用层 ) -> TCP 套接字 -> TCP 协议 ( 运输层 ) ;三、SSL 与 TSL 对比SSL 与 TSL 对比 :① 基础 : SSL / TSL 基础是 可靠的 TCP 通信 ;② WEB 支持 : 浏览器 与 WEB 服务器 , 支持 SSL / TSL ;③ 目标 : 实现 应用实体 ( 进程 ) 之间安全通信 ;④ 应用层 SSL 应用 : 应用层的任何协议都可以使用 SSL , HTTP 使用 SSL 协议 , 就变成了 HTTPS , 表明提供的是安全服务 ;⑤ 端口号 : HTTP 端口号是 80 , HTTPS 端口号是 443 ;四、SSL 服务SSL 服务 :① SSL 服务器鉴别 : 用于 鉴别 服务器身份 ; 客户端 ( 支持 SSL ) 验证 服务器 证书 , 鉴别服务器 , 并获取服务器的公钥 ;② SSL 客户端鉴别 : 服务器 验证 客户端 身份 ; ( 可选 )③ 加密 SSL 会话 : 端与端之间的 报文都进行加密 , 检测是否被篡改 ;五、SSL 安全会话建立过程SSL 安全会话建立过程 : TCP 连接之后 , 开始建立 SSL 安全会话 ;① 协商加密算法 : 浏览器 发送 SSL 版本号 , 可选的加密算法 ; 服务器 回送 自己支持的加密算法 ;② 传输公钥 : 服务器 向 浏览器 发送包含 服务器公钥的 CA 数字证书 , 浏览器使用该 CA 发布机构验证该公钥 ;③ 会话密钥计算 : 浏览器 产生 随机秘密数 , 使用 服务器公钥 加密后 , 发送给 服务器 ; 服务器 收到后 , 产生共享的 对称会话密钥 , 发送给 浏览器 ;之后进行 SSL 安全会话 ;
openssl框架闲谈--SSL实现
BIO 和EVP的一个应用就是SSL,没有SSL这个应用,BIO或者EVP只不过是一些底层的支撑接口,没有任何的现实意义,正是SSL使用了BIO和EVP 的机制提供了一个已经成型的安全套接字的实现策略。其实想象一下,安全套接字有两层含义,一层就是安全,这个由EVP接口实现了,另外一层含义就是套接 字,也就是说它必须是一个套接字,必须在操作的网络协议栈上进行IO,这一层含义是在BIO接口体现的,这个意义上,SSL正是通过组合BIO和EVP来 实现安全套接字的,BIO除了提供底层的抽象接口之外并不和SSL存在别的方面的耦合,因此BIO可以单独被使用,同样的,EVP也是可以单独被使用的。 不过,继续我们美妙的旅程之前首先要说的一点是,SSL本身就是一个BIO类型,并且是属于过滤类型的,在它的下层必须有一个socket类型的源/目的类型的BIO,在openssl中自带的sconnect实例中体现了这一点,创建过程如下: SSL_load_error_strings(); OpenSSL_add_ssl_algorithms(); ssl_ctx=SSL_CTX_new(SSLv23_client_method()); ssl=SSL_new(ssl_ctx); SSL_set_connect_state(ssl); ssl_bio=BIO_new(BIO_f_ssl()); BIO_set_ssl(ssl_bio,ssl,BIO_CLOSE); out=BIO_new(BIO_s_connect()); BIO_set_conn_hostname(out,host); BIO_set_nbio(out,1); out=BIO_push(ssl_bio,out);
本文转自 dog250 51CTO博客,原文链接:http://blog.51cto.com/dog250/1273626
HTTPS通信的C++实现
HTTPS是以安全为目标的HTTP通道,简单讲是HTTP的安全版。即HTTP下加入SSL层,HTTPS的安全基础是SSL,因此加密的详细内容就需要SSL。Nebula是一个为开发者提供一个快速开发高并发网络服务程序或搭建高并发分布式服务集群的高性能事件驱动网络框架。Nebula作为通用网络框架提供HTTPS支持十分重要,Nebula既可用作https服务器,又可用作https客户端。本文将结合Nebula框架的https实现详细讲述基于openssl的SSL编程。如果觉得本文对你有用,帮忙到Nebula的Github或码云给个star,谢谢。Nebula不仅是一个框架,还提供了一系列基于这个框架的应用,目标是打造一个高性能分布式服务集群解决方案。Nebula的主要应用领域:即时通讯(成功应用于一款IM)、消息推送平台、数据实时分析计算(成功案例)等,Bwar还计划基于Nebula开发爬虫应用。
SSL加密通信 HTTPS通信是在TCP通信层与HTTP应用层之间增加了SSL层,如果应用层不是HTTP协议也是可以使用SSL加密通信的,比如WebSocket协议WS的加上SSL层之后的WSS。Nebula框架可以通过更换Codec达到不修改代码变更通讯协议目的,Nebula增加SSL支持后,所有Nebula支持的通讯协议都有了SSL加密通讯支持,基于Nebula的业务代码无须做任何修改。
https_communication
Socket连接建立后的SSL连接建立过程:
ssl_communication
OpenSSL API OpenSSL的API很多,但并不是都会被使用到,如果需要查看某个API的详细使用方法可以阅读API文档。
2.1 初始化OpenSSL OpenSSL在使用之前,必须进行相应的初始化工作。在建立SSL连接之前,要为Client和Server分别指定本次连接采用的协议及其版本,目前能够使用的协议版本包括SSLv2、SSLv3、SSLv2/v3和TLSv1.0。SSL连接若要正常建立,则要求Client和Server必须使用相互兼容的协议。 下面是Nebula框架SocketChannelSslImpl::SslInit()函数初始化OpenSSL的代码,根据OpenSSL的不同版本调用了不同的API进行初始化。
if OPENSSL_VERSION_NUMBER >= 0x10100003L
if (OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG, NULL) == 0)
{
pLogger->WriteLog(neb::Logger::ERROR, __FILE__, __LINE__, __FUNCTION__, "OPENSSL_init_ssl() failed!");
return(ERR_SSL_INIT);
}
/*
* OPENSSL_init_ssl() may leave errors in the error queue
* while returning success
*/
ERR_clear_error();
else
OPENSSL_config(NULL);
SSL_library_init(); // 初始化SSL算法库函数( 加载要用到的算法 ),调用SSL函数之前必须调用此函数
SSL_load_error_strings(); // 错误信息的初始化
OpenSSL_add_all_algorithms();
endif
2.2 创建CTX CTX是SSL会话环境,建立连接时使用不同的协议,其CTX也不一样。创建CTX的相关OpenSSL函数:
//客户端、服务端都需要调用SSL_CTX_new(); //申请SSL会话环境
//若有验证对方证书的需求,则需调用SSL_CTX_set_verify(); //指定证书验证方式SSL_CTX_load_verify_location(); //为SSL会话环境加载本应用所信任的CA证书列表
//若有加载证书的需求,则需调用int SSL_CTX_use_certificate_file(); //为SSL会话加载本应用的证书int SSL_CTX_use_certificate_chain_file();//为SSL会话加载本应用的证书所属的证书链int SSL_CTX_use_PrivateKey_file(); //为SSL会话加载本应用的私钥int SSL_CTX_check_private_key(); //验证所加载的私钥和证书是否相匹配 2.3 创建SSL套接字 在创建SSL套接字之前要先创建Socket套接字,建立TCP连接。创建SSL套接字相关函数:
SSL SSl_new(SSL_CTX ctx); //创建一个SSL套接字int SSL_set_fd(SSL *ssl, int fd); //以读写模式绑定流套接字int SSL_set_rfd(SSL *ssl, int fd); //以只读模式绑定流套接字int SSL_set_wfd(SSL *ssl, int fd); //以只写模式绑定流套接字2.4 完成SSL握手 在这一步,我们需要在普通TCP连接的基础上,建立SSL连接。与普通流套接字建立连接的过程类似:Client使用函数SSL_connect()【类似于流套接字中用的connect()】发起握手,而Server使用函数SSL_ accept()【类似于流套接字中用的accept()】对握手进行响应,从而完成握手过程。两函数原型如下:
int SSL_connect(SSL *ssl);int SSL_accept(SSL *ssl); 握手过程完成之后,Client通常会要求Server发送证书信息,以便对Server进行鉴别。其实现会用到以下两个函数:
X509 SSL_get_peer_certificate(SSL ssl); //从SSL套接字中获取对方的证书信息X509_NAME X509_get_subject_name(X509 a); //得到证书所用者的名字2.5 数据传输 经过前面的一系列过程后,就可以进行安全的数据传输了。在数据传输阶段,需要使用SSL_read( )和SSL_write( )来代替普通流套接字所使用的read( )和write( )函数,以此完成对SSL套接字的读写操作,两个新函数的原型分别如下:
int SSL_read(SSL ssl,void buf,int num); //从SSL套接字读取数据int SSL_write(SSL ssl,const void buf,int num); //向SSL套接字写入数据2.6 会话结束 当Client和Server之间的通信过程完成后,就使用以下函数来释放前面过程中申请的SSL资源:
int SSL_shutdown(SSL *ssl); //关闭SSL套接字void SSl_free(SSL *ssl); //释放SSL套接字void SSL_CTX_free(SSL_CTX *ctx); //释放SSL会话环境
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 也被发现存在问题,所以很多浏览器直接废除了该协议版本。
Nebula中的SSL通讯实现 Nebula框架同时支持SSL服务端应用和SSL客户端应用,对openssl的初始化只需要初始化一次即可(SslInit()只需调用一次)。Nebula框架的SSL相关代码(包括客户端和服务端的实现)都封装在SocketChannelSslImpl这个类中。Nebula的SSL通信是基于异步非阻塞的socket通信,并且不使用openssl的BIO(因为没有必要,代码还更复杂了)。
SocketChannelSslImpl是SocketChannelImpl的派生类,在SocketChannelImpl常规TCP通信之上增加了SSL通信层,两个类的调用几乎没有差异。SocketChannelSslImpl类声明如下:
class SocketChannelSslImpl : public SocketChannelImpl{public:
SocketChannelSslImpl(SocketChannel* pSocketChannel, std::shared_ptr<NetLogger> pLogger, int iFd, uint32 ulSeq, ev_tstamp dKeepAlive = 0.0);
virtual ~SocketChannelSslImpl();
static int SslInit(std::shared_ptr<NetLogger> pLogger);
static int SslServerCtxCreate(std::shared_ptr<NetLogger> pLogger);
static int SslServerCertificate(std::shared_ptr<NetLogger> pLogger,
const std::string& strCertFile, const std::string& strKeyFile);
static void SslFree();
int SslClientCtxCreate();
int SslCreateConnection();
int SslHandshake();
int SslShutdown();
virtual bool Init(E_CODEC_TYPE eCodecType, bool bIsClient = false) override;
// 覆盖基类的Send()方法,实现非阻塞socket连接建立后继续建立SSL连接,并收发数据
virtual E_CODEC_STATUS Send() override;
virtual E_CODEC_STATUS Send(int32 iCmd, uint32 uiSeq, const MsgBody& oMsgBody) override;
virtual E_CODEC_STATUS Send(const HttpMsg& oHttpMsg, uint32 ulStepSeq) override;
virtual E_CODEC_STATUS Recv(MsgHead& oMsgHead, MsgBody& oMsgBody) override;
virtual E_CODEC_STATUS Recv(HttpMsg& oHttpMsg) override;
virtual E_CODEC_STATUS Recv(MsgHead& oMsgHead, MsgBody& oMsgBody, HttpMsg& oHttpMsg) override;
virtual bool Close() override;
protected:
virtual int Write(CBuffer* pBuff, int& iErrno) override;
virtual int Read(CBuffer* pBuff, int& iErrno) override;
private:
E_SSL_CHANNEL_STATUS m_eSslChannelStatus; //在基类m_ucChannelStatus通道状态基础上增加SSL通道状态
bool m_bIsClientConnection;
SSL* m_pSslConnection;
static SSL_CTX* m_pServerSslCtx; //当打开ssl选项编译,启动Nebula服务则自动创建
static SSL_CTX* m_pClientSslCtx; //默认为空,当打开ssl选项编译并且第一次发起了对其他SSL服务的连接时(比如访问一个https地址)创建
}; SocketChannelSslImpl类中带override关键字的方法都是覆盖基类SocketChannelImpl的同名方法,也是实现SSL通信与非SSL通信调用透明的关键。不带override关键字的方法都是SSL通信相关方法,这些方法里有openssl的函数调用。不带override的方法中有静态和非静态之分,静态方法在进程中只会被调用一次,与具体Channel对象无关。SocketChannel外部不需要调用非静态的ssl相关方法。
因为是非阻塞的socket,SSL_do_handshake()和SSL_write()、SSL_read()返回值并不完全能判断是否出错,还需要SSL_get_error()获取错误码。SSL_ERROR_WANT_READ和SSL_ERROR_WANT_WRITE都是正常的。
网上的大部分openssl例子程序是按顺序调用openssl函数简单实现同步ssl通信,在非阻塞IO应用中,ssl通信要复杂许多。SocketChannelSslImpl实现的是非阻塞的ssl通信,从该类的实现上看整个通信过程并非完全线性的。下面的SSL通信图更清晰地说明了Nebula框架中SSL通信是如何实现的:
Nebula_ssl
SocketChannelSslImpl中的静态方法在进程生命期内只需调用一次,也可以理解成SSL_CTX_new()、SSL_CTX_free()等方法只需调用一次。更进一步理解SSL_CTX结构体在进程内只需要创建一次(在Nebula中分别为Server和Client各创建一个)就可以为所有SSL连接所用;当然,为每个SSL连接创建独立的SSL_CTX也没问题(Nebula 0.4中实测过为每个Client创建独立的SSL_CTX),但一般不这么做,因为这样会消耗更多的内存资源,并且效率也会更低。
建立SSL连接时,客户端调用SSL_connect(),服务端调用SSL_accept(),许多openssl的demo都是这么用的。Nebula中用的是SSL_do_handshake(),这个方法同时适用于客户端和服务端,在兼具client和server功能的服务更适合用SSL_do_handshake()。注意调用SSL_do_handshake()前,如果是client端需要先调用SSL_set_connect_state(),如果是server端则需要先调用SSL_set_accept_state()。非阻塞IO中,SSL_do_handshake()可能需要调用多次才能完成握手,具体调用时机需根据SSL_get_error()获取错误码SSL_ERROR_WANT_READ和SSL_ERROR_WANT_WRITE判断需监听读事件还是写事件,在对应事件触发时再次调用SSL_do_handshake()。详细实现请参考SocketChannelSslImpl的Send和Recv方法。
关闭SSL连接时先调用SSL_shutdown()正常关闭SSL层连接(非阻塞IO中SSL_shutdown()亦可能需要调用多次)再调用SSL_free()释放SSL连接资源,最后关闭socket连接。SSL_CTX无须释放。整个SSL通信顺利完成,Nebula 0.4在开多个终端用shell脚本死循环调用curl简单压测中SSL client和SSL server功能一切正常:
while :do
curl -v -k -H "Content-Type:application/json" -X POST -d '{"hello":"nebula ssl test"}' https://192.168.157.168:16003/test_ssl
done 测试方法如下图:
ssl_test
查看资源使用情况,SSL Server端的内存使用一直在增长,疑似有内存泄漏,不过pmap -d查看某一项anon内存达到近18MB时不再增长,说明可能不是内存泄漏,只是部分内存被openssl当作cache使用了。这个问题网上没找到解决办法。从struct ssl_ctx_st结构体定义发现端倪,再从nginx源码中发现了SSL_CTX_remove_session(),于是在SSL_free()之前加上SSL_CTX_remove_session()。session复用可以提高SSL通信效率,不过Nebula暂时不需要。
这种测试方法把NebulaInterface作为SSL服务端,NebulaLogic作为SSL客户端,同时完成了Nebula框架SSL服务端和客户端功能测试,简单的压力测试。Nebula框架的SSL通信测试通过,也可以投入生产应用,在后续应用中肯定还会继续完善。openssl真的难用,难怪被吐槽那么多,或许不久之后的Nebula版本将用其他ssl库替换掉openssl。
结束 加上SSL支持的Nebula框架测试通过,虽然不算太复杂,但过程还是蛮曲折,耗时也挺长。这里把Nebula使用openssl开发SSL通信分享出来,希望对准备使用openssl的开发者有用。如果觉得本文对你有用,别忘了到Nebula的Github或码云给个star,谢谢。
基于OpenSSL的HTTPS通信C++实现
HTTPS是以安全为目标的HTTP通道,简单讲是HTTP的安全版。即HTTP下加入SSL层,HTTPS的安全基础是SSL,因此加密的详细内容就需要SSL。Nebula是一个为开发者提供一个快速开发高并发网络服务程序或搭建高并发分布式服务集群的高性能事件驱动网络框架。Nebula作为通用网络框架提供HTTPS支持十分重要,Nebula既可用作https服务器,又可用作https客户端。本文将结合Nebula框架的https实现详细讲述基于openssl的SSL编程。如果觉得本文对你有用,帮忙到Nebula的Github或码云给个star,谢谢。Nebula不仅是一个框架,还提供了一系列基于这个框架的应用,目标是打造一个高性能分布式服务集群解决方案。Nebula的主要应用领域:即时通讯(成功应用于一款IM)、消息推送平台、数据实时分析计算(成功案例)等,Bwar还计划基于Nebula开发爬虫应用。
1. SSL加密通信
HTTPS通信是在TCP通信层与HTTP应用层之间增加了SSL层,如果应用层不是HTTP协议也是可以使用SSL加密通信的,比如WebSocket协议WS的加上SSL层之后的WSS。Nebula框架可以通过更换Codec达到不修改代码变更通讯协议目的,Nebula增加SSL支持后,所有Nebula支持的通讯协议都有了SSL加密通讯支持,基于Nebula的业务代码无须做任何修改。
Socket连接建立后的SSL连接建立过程:
2. OpenSSL API
OpenSSL的API很多,但并不是都会被使用到,如果需要查看某个API的详细使用方法可以阅读API文档。
2.1 初始化OpenSSL
OpenSSL在使用之前,必须进行相应的初始化工作。在建立SSL连接之前,要为Client和Server分别指定本次连接采用的协议及其版本,目前能够使用的协议版本包括SSLv2、SSLv3、SSLv2/v3和TLSv1.0。SSL连接若要正常建立,则要求Client和Server必须使用相互兼容的协议。 下面是Nebula框架SocketChannelSslImpl::SslInit()函数初始化OpenSSL的代码,根据OpenSSL的不同版本调用了不同的API进行初始化。
#if OPENSSL_VERSION_NUMBER >= 0x10100003L
if (OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG, NULL) == 0)
{
pLogger->WriteLog(neb::Logger::ERROR, __FILE__, __LINE__, __FUNCTION__, "OPENSSL_init_ssl() failed!");
return(ERR_SSL_INIT);
}
/*
* OPENSSL_init_ssl() may leave errors in the error queue
* while returning success
*/
ERR_clear_error();
#else
OPENSSL_config(NULL);
SSL_library_init(); // 初始化SSL算法库函数( 加载要用到的算法 ),调用SSL函数之前必须调用此函数
SSL_load_error_strings(); // 错误信息的初始化
OpenSSL_add_all_algorithms();
#endif
2.2 创建CTX
CTX是SSL会话环境,建立连接时使用不同的协议,其CTX也不一样。创建CTX的相关OpenSSL函数:
//客户端、服务端都需要调用
SSL_CTX_new(); //申请SSL会话环境
//若有验证对方证书的需求,则需调用
SSL_CTX_set_verify(); //指定证书验证方式
SSL_CTX_load_verify_location(); //为SSL会话环境加载本应用所信任的CA证书列表
//若有加载证书的需求,则需调用
int SSL_CTX_use_certificate_file(); //为SSL会话加载本应用的证书
int SSL_CTX_use_certificate_chain_file();//为SSL会话加载本应用的证书所属的证书链
int SSL_CTX_use_PrivateKey_file(); //为SSL会话加载本应用的私钥
int SSL_CTX_check_private_key(); //验证所加载的私钥和证书是否相匹配
2.3 创建SSL套接字
在创建SSL套接字之前要先创建Socket套接字,建立TCP连接。创建SSL套接字相关函数:
SSL *SSl_new(SSL_CTX *ctx); //创建一个SSL套接字
int SSL_set_fd(SSL *ssl, int fd); //以读写模式绑定流套接字
int SSL_set_rfd(SSL *ssl, int fd); //以只读模式绑定流套接字
int SSL_set_wfd(SSL *ssl, int fd); //以只写模式绑定流套接字
2.4 完成SSL握手
在这一步,我们需要在普通TCP连接的基础上,建立SSL连接。与普通流套接字建立连接的过程类似:Client使用函数SSL_connect()【类似于流套接字中用的connect()】发起握手,而Server使用函数SSL_ accept()【类似于流套接字中用的accept()】对握手进行响应,从而完成握手过程。两函数原型如下:
int SSL_connect(SSL *ssl);
int SSL_accept(SSL *ssl);
握手过程完成之后,Client通常会要求Server发送证书信息,以便对Server进行鉴别。其实现会用到以下两个函数:
X509 *SSL_get_peer_certificate(SSL *ssl); //从SSL套接字中获取对方的证书信息
X509_NAME *X509_get_subject_name(X509 *a); //得到证书所用者的名字
2.5 数据传输
经过前面的一系列过程后,就可以进行安全的数据传输了。在数据传输阶段,需要使用SSL_read( )和SSL_write( )来代替普通流套接字所使用的read( )和write( )函数,以此完成对SSL套接字的读写操作,两个新函数的原型分别如下:
int SSL_read(SSL *ssl,void *buf,int num); //从SSL套接字读取数据
int SSL_write(SSL *ssl,const void *buf,int num); //向SSL套接字写入数据
2.6 会话结束
当Client和Server之间的通信过程完成后,就使用以下函数来释放前面过程中申请的SSL资源:
int SSL_shutdown(SSL *ssl); //关闭SSL套接字
void SSl_free(SSL *ssl); //释放SSL套接字
void SSL_CTX_free(SSL_CTX *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 也被发现存在问题,所以很多浏览器直接废除了该协议版本。
4. Nebula中的SSL通讯实现
Nebula框架同时支持SSL服务端应用和SSL客户端应用,对openssl的初始化只需要初始化一次即可(SslInit()只需调用一次)。Nebula框架的SSL相关代码(包括客户端和服务端的实现)都封装在SocketChannelSslImpl这个类中。Nebula的SSL通信是基于异步非阻塞的socket通信,并且不使用openssl的BIO(因为没有必要,代码还更复杂了)。
SocketChannelSslImpl是SocketChannelImpl的派生类,在SocketChannelImpl常规TCP通信之上增加了SSL通信层,两个类的调用几乎没有差异。SocketChannelSslImpl类声明如下:
class SocketChannelSslImpl : public SocketChannelImpl
{
public:
SocketChannelSslImpl(SocketChannel* pSocketChannel, std::shared_ptr<NetLogger> pLogger, int iFd, uint32 ulSeq, ev_tstamp dKeepAlive = 0.0);
virtual ~SocketChannelSslImpl();
static int SslInit(std::shared_ptr<NetLogger> pLogger);
static int SslServerCtxCreate(std::shared_ptr<NetLogger> pLogger);
static int SslServerCertificate(std::shared_ptr<NetLogger> pLogger,
const std::string& strCertFile, const std::string& strKeyFile);
static void SslFree();
int SslClientCtxCreate();
int SslCreateConnection();
int SslHandshake();
int SslShutdown();
virtual bool Init(E_CODEC_TYPE eCodecType, bool bIsClient = false) override;
// 覆盖基类的Send()方法,实现非阻塞socket连接建立后继续建立SSL连接,并收发数据
virtual E_CODEC_STATUS Send() override;
virtual E_CODEC_STATUS Send(int32 iCmd, uint32 uiSeq, const MsgBody& oMsgBody) override;
virtual E_CODEC_STATUS Send(const HttpMsg& oHttpMsg, uint32 ulStepSeq) override;
virtual E_CODEC_STATUS Recv(MsgHead& oMsgHead, MsgBody& oMsgBody) override;
virtual E_CODEC_STATUS Recv(HttpMsg& oHttpMsg) override;
virtual E_CODEC_STATUS Recv(MsgHead& oMsgHead, MsgBody& oMsgBody, HttpMsg& oHttpMsg) override;
virtual bool Close() override;
protected:
virtual int Write(CBuffer* pBuff, int& iErrno) override;
virtual int Read(CBuffer* pBuff, int& iErrno) override;
private:
E_SSL_CHANNEL_STATUS m_eSslChannelStatus; //在基类m_ucChannelStatus通道状态基础上增加SSL通道状态
bool m_bIsClientConnection;
SSL* m_pSslConnection;
static SSL_CTX* m_pServerSslCtx; //当打开ssl选项编译,启动Nebula服务则自动创建
static SSL_CTX* m_pClientSslCtx; //默认为空,当打开ssl选项编译并且第一次发起了对其他SSL服务的连接时(比如访问一个https地址)创建
};
SocketChannelSslImpl类中带override关键字的方法都是覆盖基类SocketChannelImpl的同名方法,也是实现SSL通信与非SSL通信调用透明的关键。不带override关键字的方法都是SSL通信相关方法,这些方法里有openssl的函数调用。不带override的方法中有静态和非静态之分,静态方法在进程中只会被调用一次,与具体Channel对象无关。SocketChannel外部不需要调用非静态的ssl相关方法。
因为是非阻塞的socket,SSL_do_handshake()和SSL_write()、SSL_read()返回值并不完全能判断是否出错,还需要SSL_get_error()获取错误码。SSL_ERROR_WANT_READ和SSL_ERROR_WANT_WRITE都是正常的。
网上的大部分openssl例子程序是按顺序调用openssl函数简单实现同步ssl通信,在非阻塞IO应用中,ssl通信要复杂许多。SocketChannelSslImpl实现的是非阻塞的ssl通信,从该类的实现上看整个通信过程并非完全线性的。下面的SSL通信图更清晰地说明了Nebula框架中SSL通信是如何实现的:
SocketChannelSslImpl中的静态方法在进程生命期内只需调用一次,也可以理解成SSL_CTX_new()、SSL_CTX_free()等方法只需调用一次。更进一步理解SSL_CTX结构体在进程内只需要创建一次(在Nebula中分别为Server和Client各创建一个)就可以为所有SSL连接所用;当然,为每个SSL连接创建独立的SSL_CTX也没问题(Nebula 0.4中实测过为每个Client创建独立的SSL_CTX),但一般不这么做,因为这样会消耗更多的内存资源,并且效率也会更低。
建立SSL连接时,客户端调用SSL_connect(),服务端调用SSL_accept(),许多openssl的demo都是这么用的。Nebula中用的是SSL_do_handshake(),这个方法同时适用于客户端和服务端,在兼具client和server功能的服务更适合用SSL_do_handshake()。注意调用SSL_do_handshake()前,如果是client端需要先调用SSL_set_connect_state(),如果是server端则需要先调用SSL_set_accept_state()。非阻塞IO中,SSL_do_handshake()可能需要调用多次才能完成握手,具体调用时机需根据SSL_get_error()获取错误码SSL_ERROR_WANT_READ和SSL_ERROR_WANT_WRITE判断需监听读事件还是写事件,在对应事件触发时再次调用SSL_do_handshake()。详细实现请参考SocketChannelSslImpl的Send和Recv方法。
关闭SSL连接时先调用SSL_shutdown()正常关闭SSL层连接(非阻塞IO中SSL_shutdown()亦可能需要调用多次)再调用SSL_free()释放SSL连接资源,最后关闭socket连接。SSL_CTX无须释放。整个SSL通信顺利完成,Nebula 0.4在开多个终端用shell脚本死循环调用curl简单压测中SSL client和SSL server功能一切正常:
while :
do
curl -v -k -H "Content-Type:application/json" -X POST -d '{"hello":"nebula ssl test"}' https://192.168.157.168:16003/test_ssl
done
测试方法如下图:
查看资源使用情况,SSL Server端的内存使用一直在增长,疑似有内存泄漏,不过pmap -d查看某一项anon内存达到近18MB时不再增长,说明可能不是内存泄漏,只是部分内存被openssl当作cache使用了。这个问题网上没找到解决办法。从struct ssl_ctx_st结构体定义发现端倪,再从nginx源码中发现了SSL_CTX_remove_session(),于是在SSL_free()之前加上SSL_CTX_remove_session()。session复用可以提高SSL通信效率,不过Nebula暂时不需要。
这种测试方法把NebulaInterface作为SSL服务端,NebulaLogic作为SSL客户端,同时完成了Nebula框架SSL服务端和客户端功能测试,简单的压力测试。Nebula框架的SSL通信测试通过,也可以投入生产应用,在后续应用中肯定还会继续完善。openssl真的难用,难怪被吐槽那么多,或许不久之后的Nebula版本将用其他ssl库替换掉openssl。
5. 结束
加上SSL支持的Nebula框架测试通过,虽然不算太复杂,但过程还是蛮曲折,耗时也挺长。这里把Nebula使用openssl开发SSL通信分享出来,希望对准备使用openssl的开发者有用。如果觉得本文对你有用,别忘了到Nebula的Github或码云给个star,谢谢。
HTTPS通信的C++实现
HTTPS是以安全为目标的HTTP通道,简单讲是HTTP的安全版。即HTTP下加入SSL层,HTTPS的安全基础是SSL,因此加密的详细内容就需要SSL。Nebula是一个为开发者提供一个快速开发高并发网络服务程序或搭建高并发分布式服务集群的高性能事件驱动网络框架。Nebula作为通用网络框架提供HTTPS支持十分重要,Nebula既可用作https服务器,又可用作https客户端。本文将结合Nebula框架的https实现详细讲述基于openssl的SSL编程。如果觉得本文对你有用,帮忙到Nebula的Github或码云给个star,谢谢。Nebula不仅是一个框架,还提供了一系列基于这个框架的应用,目标是打造一个高性能分布式服务集群解决方案。Nebula的主要应用领域:即时通讯(成功应用于一款IM)、消息推送平台、数据实时分析计算(成功案例)等,Bwar还计划基于Nebula开发爬虫应用。
1. SSL加密通信
HTTPS通信是在TCP通信层与HTTP应用层之间增加了SSL层,如果应用层不是HTTP协议也是可以使用SSL加密通信的,比如WebSocket协议WS的加上SSL层之后的WSS。Nebula框架可以通过更换Codec达到不修改代码变更通讯协议目的,Nebula增加SSL支持后,所有Nebula支持的通讯协议都有了SSL加密通讯支持,基于Nebula的业务代码无须做任何修改。
Socket连接建立后的SSL连接建立过程:
2. OpenSSL API
OpenSSL的API很多,但并不是都会被使用到,如果需要查看某个API的详细使用方法可以阅读API文档。
2.1 初始化OpenSSL
OpenSSL在使用之前,必须进行相应的初始化工作。在建立SSL连接之前,要为Client和Server分别指定本次连接采用的协议及其版本,目前能够使用的协议版本包括SSLv2、SSLv3、SSLv2/v3和TLSv1.0。SSL连接若要正常建立,则要求Client和Server必须使用相互兼容的协议。 下面是Nebula框架SocketChannelSslImpl::SslInit()函数初始化OpenSSL的代码,根据OpenSSL的不同版本调用了不同的API进行初始化。
#if OPENSSL_VERSION_NUMBER >= 0x10100003L
if (OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG, NULL) == 0)
{
pLogger->WriteLog(neb::Logger::ERROR, __FILE__, __LINE__, __FUNCTION__, "OPENSSL_init_ssl() failed!");
return(ERR_SSL_INIT);
}
/*
* OPENSSL_init_ssl() may leave errors in the error queue
* while returning success
*/
ERR_clear_error();
#else
OPENSSL_config(NULL);
SSL_library_init(); // 初始化SSL算法库函数( 加载要用到的算法 ),调用SSL函数之前必须调用此函数
SSL_load_error_strings(); // 错误信息的初始化
OpenSSL_add_all_algorithms();
#endif
2.2 创建CTX
CTX是SSL会话环境,建立连接时使用不同的协议,其CTX也不一样。创建CTX的相关OpenSSL函数:
//客户端、服务端都需要调用
SSL_CTX_new(); //申请SSL会话环境
//若有验证对方证书的需求,则需调用
SSL_CTX_set_verify(); //指定证书验证方式
SSL_CTX_load_verify_location(); //为SSL会话环境加载本应用所信任的CA证书列表
//若有加载证书的需求,则需调用
int SSL_CTX_use_certificate_file(); //为SSL会话加载本应用的证书
int SSL_CTX_use_certificate_chain_file();//为SSL会话加载本应用的证书所属的证书链
int SSL_CTX_use_PrivateKey_file(); //为SSL会话加载本应用的私钥
int SSL_CTX_check_private_key(); //验证所加载的私钥和证书是否相匹配
2.3 创建SSL套接字
在创建SSL套接字之前要先创建Socket套接字,建立TCP连接。创建SSL套接字相关函数:
SSL *SSl_new(SSL_CTX *ctx); //创建一个SSL套接字
int SSL_set_fd(SSL *ssl, int fd); //以读写模式绑定流套接字
int SSL_set_rfd(SSL *ssl, int fd); //以只读模式绑定流套接字
int SSL_set_wfd(SSL *ssl, int fd); //以只写模式绑定流套接字
2.4 完成SSL握手
在这一步,我们需要在普通TCP连接的基础上,建立SSL连接。与普通流套接字建立连接的过程类似:Client使用函数SSL_connect()【类似于流套接字中用的connect()】发起握手,而Server使用函数SSL_ accept()【类似于流套接字中用的accept()】对握手进行响应,从而完成握手过程。两函数原型如下:
int SSL_connect(SSL *ssl);
int SSL_accept(SSL *ssl);
握手过程完成之后,Client通常会要求Server发送证书信息,以便对Server进行鉴别。其实现会用到以下两个函数:
X509 *SSL_get_peer_certificate(SSL *ssl); //从SSL套接字中获取对方的证书信息
X509_NAME *X509_get_subject_name(X509 *a); //得到证书所用者的名字
2.5 数据传输
经过前面的一系列过程后,就可以进行安全的数据传输了。在数据传输阶段,需要使用SSL_read( )和SSL_write( )来代替普通流套接字所使用的read( )和write( )函数,以此完成对SSL套接字的读写操作,两个新函数的原型分别如下:
int SSL_read(SSL *ssl,void *buf,int num); //从SSL套接字读取数据
int SSL_write(SSL *ssl,const void *buf,int num); //向SSL套接字写入数据
2.6 会话结束
当Client和Server之间的通信过程完成后,就使用以下函数来释放前面过程中申请的SSL资源:
int SSL_shutdown(SSL *ssl); //关闭SSL套接字
void SSl_free(SSL *ssl); //释放SSL套接字
void SSL_CTX_free(SSL_CTX *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 也被发现存在问题,所以很多浏览器直接废除了该协议版本。
4. Nebula中的SSL通讯实现
Nebula框架同时支持SSL服务端应用和SSL客户端应用,对openssl的初始化只需要初始化一次即可(SslInit()只需调用一次)。Nebula框架的SSL相关代码(包括客户端和服务端的实现)都封装在SocketChannelSslImpl这个类中。Nebula的SSL通信是基于异步非阻塞的socket通信,并且不使用openssl的BIO(因为没有必要,代码还更复杂了)。
SocketChannelSslImpl是SocketChannelImpl的派生类,在SocketChannelImpl常规TCP通信之上增加了SSL通信层,两个类的调用几乎没有差异。SocketChannelSslImpl类声明如下:
class SocketChannelSslImpl : public SocketChannelImpl
{
public:
SocketChannelSslImpl(SocketChannel* pSocketChannel, std::shared_ptr<NetLogger> pLogger, int iFd, uint32 ulSeq, ev_tstamp dKeepAlive = 0.0);
virtual ~SocketChannelSslImpl();
static int SslInit(std::shared_ptr<NetLogger> pLogger);
static int SslServerCtxCreate(std::shared_ptr<NetLogger> pLogger);
static int SslServerCertificate(std::shared_ptr<NetLogger> pLogger,
const std::string& strCertFile, const std::string& strKeyFile);
static void SslFree();
int SslClientCtxCreate();
int SslCreateConnection();
int SslHandshake();
int SslShutdown();
virtual bool Init(E_CODEC_TYPE eCodecType, bool bIsClient = false) override;
// 覆盖基类的Send()方法,实现非阻塞socket连接建立后继续建立SSL连接,并收发数据
virtual E_CODEC_STATUS Send() override;
virtual E_CODEC_STATUS Send(int32 iCmd, uint32 uiSeq, const MsgBody& oMsgBody) override;
virtual E_CODEC_STATUS Send(const HttpMsg& oHttpMsg, uint32 ulStepSeq) override;
virtual E_CODEC_STATUS Recv(MsgHead& oMsgHead, MsgBody& oMsgBody) override;
virtual E_CODEC_STATUS Recv(HttpMsg& oHttpMsg) override;
virtual E_CODEC_STATUS Recv(MsgHead& oMsgHead, MsgBody& oMsgBody, HttpMsg& oHttpMsg) override;
virtual bool Close() override;
protected:
virtual int Write(CBuffer* pBuff, int& iErrno) override;
virtual int Read(CBuffer* pBuff, int& iErrno) override;
private:
E_SSL_CHANNEL_STATUS m_eSslChannelStatus; //在基类m_ucChannelStatus通道状态基础上增加SSL通道状态
bool m_bIsClientConnection;
SSL* m_pSslConnection;
static SSL_CTX* m_pServerSslCtx; //当打开ssl选项编译,启动Nebula服务则自动创建
static SSL_CTX* m_pClientSslCtx; //默认为空,当打开ssl选项编译并且第一次发起了对其他SSL服务的连接时(比如访问一个https地址)创建
};
SocketChannelSslImpl类中带override关键字的方法都是覆盖基类SocketChannelImpl的同名方法,也是实现SSL通信与非SSL通信调用透明的关键。不带override关键字的方法都是SSL通信相关方法,这些方法里有openssl的函数调用。不带override的方法中有静态和非静态之分,静态方法在进程中只会被调用一次,与具体Channel对象无关。SocketChannel外部不需要调用非静态的ssl相关方法。
因为是非阻塞的socket,SSL_do_handshake()和SSL_write()、SSL_read()返回值并不完全能判断是否出错,还需要SSL_get_error()获取错误码。SSL_ERROR_WANT_READ和SSL_ERROR_WANT_WRITE都是正常的。
网上的大部分openssl例子程序是按顺序调用openssl函数简单实现同步ssl通信,在非阻塞IO应用中,ssl通信要复杂许多。SocketChannelSslImpl实现的是非阻塞的ssl通信,从该类的实现上看整个通信过程并非完全线性的。下面的SSL通信图更清晰地说明了Nebula框架中SSL通信是如何实现的:
SocketChannelSslImpl中的静态方法在进程生命期内只需调用一次,也可以理解成SSL_CTX_new()、SSL_CTX_free()等方法只需调用一次。更进一步理解SSL_CTX结构体在进程内只需要创建一次(在Nebula中分别为Server和Client各创建一个)就可以为所有SSL连接所用;当然,为每个SSL连接创建独立的SSL_CTX也没问题(Nebula 0.4中实测过为每个Client创建独立的SSL_CTX),但一般不这么做,因为这样会消耗更多的内存资源,并且效率也会更低。
建立SSL连接时,客户端调用SSL_connect(),服务端调用SSL_accept(),许多openssl的demo都是这么用的。Nebula中用的是SSL_do_handshake(),这个方法同时适用于客户端和服务端,在兼具client和server功能的服务更适合用SSL_do_handshake()。注意调用SSL_do_handshake()前,如果是client端需要先调用SSL_set_connect_state(),如果是server端则需要先调用SSL_set_accept_state()。非阻塞IO中,SSL_do_handshake()可能需要调用多次才能完成握手,具体调用时机需根据SSL_get_error()获取错误码SSL_ERROR_WANT_READ和SSL_ERROR_WANT_WRITE判断需监听读事件还是写事件,在对应事件触发时再次调用SSL_do_handshake()。详细实现请参考SocketChannelSslImpl的Send和Recv方法。
关闭SSL连接时先调用SSL_shutdown()正常关闭SSL层连接(非阻塞IO中SSL_shutdown()亦可能需要调用多次)再调用SSL_free()释放SSL连接资源,最后关闭socket连接。SSL_CTX无须释放。整个SSL通信顺利完成,Nebula 0.4在开多个终端用shell脚本死循环调用curl简单压测中SSL client和SSL server功能一切正常:
while :
do
curl -v -k -H "Content-Type:application/json" -X POST -d '{"hello":"nebula ssl test"}' https://192.168.157.168:16003/test_ssl
done
测试方法如下图:
查看资源使用情况,SSL Server端的内存使用一直在增长,疑似有内存泄漏,不过pmap -d查看某一项anon内存达到近18MB时不再增长,说明可能不是内存泄漏,只是部分内存被openssl当作cache使用了。这个问题网上没找到解决办法。从struct ssl_ctx_st结构体定义发现端倪,再从nginx源码中发现了SSL_CTX_remove_session(),于是在SSL_free()之前加上SSL_CTX_remove_session()。session复用可以提高SSL通信效率,不过Nebula暂时不需要。
这种测试方法把NebulaInterface作为SSL服务端,NebulaLogic作为SSL客户端,同时完成了Nebula框架SSL服务端和客户端功能测试,简单的压力测试。Nebula框架的SSL通信测试通过,也可以投入生产应用,在后续应用中肯定还会继续完善。openssl真的难用,难怪被吐槽那么多,或许不久之后的Nebula版本将用其他ssl库替换掉openssl。
5. 结束
加上SSL支持的Nebula框架测试通过,虽然不算太复杂,但过程还是蛮曲折,耗时也挺长。这里把Nebula使用openssl开发SSL通信分享出来,希望对准备使用openssl的开发者有用。如果觉得本文对你有用,别忘了到Nebula的Github或码云给个star,谢谢。
本文来自云栖社区合作伙伴“开源中国”
本文作者:Bwar
原文链接
SDK移植到设备时采用MQTT接入是否必须实现SSL接口
SDK移植到mcu环境,使用MQTT接入,是否必须实现SSL接口才可以使用?接口实现起来比较麻烦
如下接口:
HAL_SSL_Destroy
HAL_SSL_Establish
HAL_SSL_Read
HAL_SSL_Write
谢谢
SSL 隧道
SSL VPN概述 SSL VPN是一种远程安全接入技术,因为采用SSL协议而得名。因为Web浏览器都内嵌支持SSL协议,使得SSL VPN可以做到“无客户端”部署,从而使得远程安全接入的使用非常简单,而且整个系统更加易于维护。SSL VPN一般采用插件系统来支持各种TCP和UDP的非Web应用,使得SSL VPN真正称得上是一种VPN,并相对IPSec VPN更符合应用安全的需求,成为远程安全接入主要手段和选择。SSL协议SSL协议分析SSL协议主要通过三个协议实现: SSL握手协议:SSL握手协议被封装在记录协议中,该协议允许服务器与客户机在应用程序传输和接收数据之前互相认证、协商加密算法和密钥。在初次建立SSL连接时,服务器与客户机交换一系列消息。 SSL修改密文协议:保障SSL传输过程的安全性,客户端和服务器双方应该每隔一段时间改变加密规范。 SSL报警协议:SSL报警协议是用来为对等实体传递SSL的相关警告。如果在通信过程中某一方发现任何异常,就需要给对方发送一条警示消息通告。 SSL握手协议 SSL连接的建议,主要依靠SSL握手协议,简短的一句话就可以概括SSL握手协议的基本设计思路:采用公钥加密算法进行密文传输。也就是说,服务端将其公钥告诉客户端,然后客户端采用服务器的公钥加密信息,服务端收到密文后,用自己的私钥解密。 公钥加密算法又称非对称加密算法,其工作原理如下: (1)客户端A要向服务器B发送消息,B要产生一对用户加密和解密的公钥和私钥。 (2)B的私钥自己保存,B的公钥告诉A。 (3)A要给B发送信息时,用B的公钥加密信息,因为A知道B的公钥。 (4)B收到这个信息后,用自己的私钥解密。其他所有收到这个报文的人都无法解密,因为只有B有自己的私钥 (5)B要给A发送消息时,也同理用A的公钥加密,A用自己的私钥解密。SSL VPN技术优势 SSL VPN配置 SSL VPN授权SSL VPN用户数:SSL VPN并发接入用户数授权 IPSec移动用户数:SANGFOR VPN移动端PDLAN并发用户数授权 线路数:外网WAN口线路数授权 分支机构数:与第三方设备对接标准IPSEC VPN隧道数SSL VPN基础配置 1、创建用户(根据实际应用场景,选择用户的认证方式,也可多重认证方式组合认证)2、发布资源(根据需求发布成所需类型,资源类型有WEB类型、TCP类型、L3VPN类型三种类型)3、创建角色(角色的作用是将用户跟资源关联起来,其效果是让用户具有访问哪些资源的权限)测试效果:用户张三接入VPN后具备访问ERP系统的权限,除了访问此资源,其他资源都没有权限访问。SSL保护的是应用层的数据,可以针对某个应用做具体保护。IPSec针对的是整个网络层,无法做精细化控制。在SSL 出现之前,IPSec、L2TP等先期出现的技术虽然可以支持远程接入这个应用场景,但这些技术存在缺陷: 远程用户终端上需要安装指定的客户端软件,导致网络部署、维护比较麻烦。 IPSec/L2TP的配置繁琐。 网络管理人员无法对远程用户访问企业内网资源的权限做精细化控制。
数据库必知词汇:安全套接层(SSL)
SSL(Secure Sockets Layer 安全套接层),及其继任者传输层安全(Transport Layer Security,TLS)是为网络通信提供安全及数据完整性的一种安全协议。TLS与SSL在传输层与应用层之间对网络连接进行加密。
Secure Socket Layer,为Netscape研发,用以保障在Internet上数据传输的安全,利用数据加密(Encryption)技术,可确保数据在网络上的传输过程中不会被截取及窃听。一般通用的规格为40 bit的安全标准,美国则已推出128 bit的更高安全标准。只要3.0版本以上的I.E.或Netscape浏览器即可支持SSL。它已被广泛地用于Web浏览器与服务器之间的身份认证和加密数据传输。
SSL协议位于TCP/IP协议与各种应用层协议之间,为数据通讯提供安全支持。SSL协议可分为两层: SSL记录协议(SSL Record Protocol):它建立在可靠的传输协议(如TCP)之上,为高层协议提供数据封装、压缩、加密等基本功能的支持。 SSL握手协议(SSL Handshake Protocol):它建立在SSL记录协议之上,用于在实际的数据传输开始前,通讯双方进行身份认证、协商加密算法、交换加密密钥等。
SSL所提供的服务包括:
认证用户和服务器,确保数据发送到正确的客户机和服务器;
加密数据以防止数据中途被窃取;
维护数据的完整性,确保数据在传输过程中不被改变。
一份 SSL 证书包括一个公共密钥和一个私用密钥。公共密钥用于加密信息,私用密钥用于解译加密的信息。浏览器指向一个安全域时,SSL 同步确认服务器和客户端,并创建一种加密方式和一个唯一的会话密钥。它们可以启动一个保证消息的隐私性和完整性的安全会话。
SSL-VPN网关新品发布
继阿里云网关产品IPSec-VPN发布后,其安全、可靠、便捷、经济的混合云接入方案成为众多客户的选择。与此同时,越来越多的客户开始关注何时Internet各终端也可以随时随地、安全接入VPC,全面实现企业内部混合云网络互联。
本次SSL-VPN网关产品的上新发布,满足您对如上诉求的所有期待。通过本场直播您可以了解到:
1、阿里云VPN网关产品适用的主要场景;
2、SSL-VPN新网关产品有哪些优势;
3、如何开通和配置SSL-VPN网关;
4、任何您关心的其它问题......
SSL证书
一、什么是SSL证书?
首先说明SSL(安全套接层,Secure Sockets Layer)是一种安全协议,目的是为互联网通信,提供安全及数据完整性保障。SSL证书遵循SSL协议,可安装在服务器上,实现数据传输加密。
CA(数字证书认证,Certificate Authority)机构,是承担公钥合法性检验的第三方权威机构,负责指定政策、步骤来验证用户的身份,并对SSL证书进行签名,确保证书持有者的身份和公钥的所有权。CA机构为每个使用公开密钥的用户发放一个SSL证书,SSL证书的作用是证明证书中列出的个人/企业合法拥有证书中列出的公开密钥。CA机构的数字签名使得攻击者不能伪造和篡改证书。
SSL证书实际上就是CA机构对用户公钥的认证,内容包括电子签证机关的信息、公钥用户信息、公钥、权威机构的签字和有效期等。
二、SSL数字证书类型及区别
用于网站HTTPS化的SSL数字证书,当前主要分为DV SSL、OV SSL、EV SSL三种类型的证书。
DV SSL数字证书部署在服务器上后,用户浏览器访问网站时,展示如下,
OV SSL数字证书部署在服务器上后,用户浏览器访问网站时,展示如下,
EV SSL数字证书部署在服务器上后,用户浏览器访问网站时,展示如下,
区别简述如下,
数字证书
DV SSL
OV SSL
EV SSL
用户建议
个人
组织、企业
大型企业、金融机构
公信等级
一般
高
强
认证强度
网站真实性
组织及企业真实性
严格认证
安全性
一般
中
高
可信度
常规
中
高(地址栏绿色)
三、SSL证书的有什么优势?
对比传统的加密方式,SSL 证书有以下几点优势
1) 简单快捷,只需要申请一张证书,部署在服务器上,就可以在有效期内不用再做其他的操作。
2) 显示直观,部署SSL证书后,通过https访问网站,能在地址栏或地址栏右侧直接看到加密锁标志能直观的表明网站是加密的!使用 EV 证书,甚至能直接在地址栏看到公司名称。
3) 身份认证,这是别的加密方式都不具备的,能在证书信息里面看到网站所有者公司信息,进而确认网站的有效性和真实性,不会被钓鱼网站所欺骗。
四、免费SSL证书
免费SSL证书属于 Domain Validation SSL 或 DV SSL证书。是 WoSign 基础级 (Class 1) SSL证书产品,只验证域名所有权, 无需注册,快速颁发,保证了网站的机密信息从用户浏览器到服务器之间的传输是高强度加密传输的,是不会被非法窃取和非法篡改的。请参考《如何识别 DV SSL 证书》。
请注意: 免费SSL证书仅适合于个人网站或非电子商务网站,不显示单位名称,仅起到加密传输信息的作用,并不能证明网站的真实身份。由于此类只验证域名所有权的低端SSL证书已经被国外各种欺诈网站滥用,企业不推荐电子商务网站选购此类证书,推荐选购 OV SSL证书 或 EV SSL证书。