加密通信的基础 - 全面解读SSL/TLS协议

10 篇文章 1 订阅
订阅专栏

概述

  • SSL/TLS是世界上应用最广泛的密码通信方法。比如,在网上商城输入信用卡卡号时,Web浏览器就会使用SSL/TLS进行密码通信。使用SSL/TLS可以对通信对象进行认证,还可以确保通信内容的机密性。TLS相当于SSL的后续版本。
  • SSL (Secure Sockets Layer)安全套接层协议 :由Netscape公司开发。协议的第一个版本从未发布过,第二个版于1994年11月发布,但是存在严重漏洞,最终退出历史舞台。1995年年底,第三个版本SSL 3.0发布,此版本是完全重新设计的协议,因此该设计一直沿用到今天。
  • TLS(Transport Layer Security)安全传输层协议:1996年5月,TLS工作组成立,开始将SSL从Netscape迁移至IETF。最终,TLS 1.0于1999年1月问世,与SSL 3.0版本相比修改并不大,但还是改名为TLS。2006年4月,TLS 1.1发布,修复了一些关键的安全性问题。2008年8月,TLS 1.2发布,该版本添加了对已验证加密的支持,并且基本上删除了协议说明中所有硬编码的安全基元,使协议完全弹性化。

SSL/TLS、HTTP、HTTPS关系

  • HTTPS是安全版本的HTTP,简单理解 HTTPS = HTTP + SSL/TLS,即HTTPS就是使用SSL/TLS协议对HTTP报文进行了加密处理。
    在这里插入图片描述

SSL/TLS单向认证和双向认证

  • 单向认证指的是通信双方只校验一方发送过来的数字证书,另一方不校验。通常是客户端根据服务器传过来的证书信息校验服务器的合法性。
  • 双向认证指的是在通信双方都要校验对方发送过来的数字证书,一般应用于对安全性要求更高的领域。

SSL/TLS握手过程

  • 这里先重点介绍下SSL/TLS双向认证的握手过程,SSL/TLS单向认证后面也会提到,并进行比对。
  • TLS握手涉及到加密算法和数字证书的知识。不了解的可参考我的另外两篇文章。 加密算法简介 数字证书简介
  • 握手图示 图中虚线部分是双向认证时需要额外发送的消息。
client server 生成客户端随机数 Client Hello 客户端随机数,客户端TLS版本,密码套件列表 生成服务端随机数 Server Hello 服务端随机数,确认TLS版本号,确认密码套件 Server Certificate 发送服务端证书 Server Key ExChange Certificate Request 表示想要收到客户端的证书 Server Hello Done Client Certificate 发送客户端证书 生成预备主密钥PreMaster 使用服务端证书中的公钥加密 预主密钥得到Encrypted PreMaster Client Key Exchange 发送加密后的预备主密钥 Encrypted PreMaster 使用私钥解密Encrypted PreMaster 得到预备主密钥PreMaster 使用客户端随机数,服务端随机数 预备主密钥 计算出主密钥 使用客户端随机数,服务端随机数 预备主密钥 计算出主密钥 Certificate verify 证书验证,表示我就是客户端证书本人 Change Cipher Spec 密钥协商完成 Finished [Encrypted Handshake Message] 握手协议结束 Change Cipher Spec 密钥协商完成 Finished [Encrypted Handshake Message] 握手协议结束 client server
  • 备注:不同的密钥协商算法计算预备主密钥的方法不一样,这里展示的是RSA密钥协商算法计算预备主密钥的方法。
  • 握手详解
    • [1] Client Hello
      • 客户端发送TLS版本,支持的加密套件列表给服务端,并生成客户端随机数发送给服务端。
      • Version : 表示客户端支持的SSL/TLS协议版本
      • Random : 客户端随机数
      • Session ID : 和会话恢复有关
      • Cipher Suites : 客户端支持的密码套件列表
        在这里插入图片描述 在这里插入图片描述
      • Compression Methods : 客户端支持的压缩方法
      • Extension : 扩展项
    • [2] Server Hello
      • 服务端确认TLS版本,选择使用的加密套件,生成服务端随机数发送给客户端。
      • Version : 服务端根据客户端传递的版本号,选择一个双方都支持的版本
      • Random : 服务端随机数
      • Session ID : 和会话恢复有关
      • Cipher Suite : 根据客户端传递过来的密码套件列表,选择一个双方都支持的密码套件
      • Compression Method : 压缩算法
      • Extension : 扩展项
    • [3] Server Certificate
      • 该消息是可选的。根据协商出来的密码套件,服务端选择是否发送证书消息。在HTTPS网站中一般服务器会发送证书,如果协商出的密码套件是DH_anon或者ECDH_anon,则服务器不发送该消息,可能会遇到中间人攻击。
      • 服务器发送证书一般有两个目的:一是进行身份验证,二是证书中包含服务器的公钥,该公钥结合密码套件的密钥协商算法协商出预备主密钥。
    • [4] Server Key Exchange
      • 该消息是有条件才发送的。如果证书包含的信息不足以进行密钥交换,那么必须发送该消息。
      • 下列的密码套件,服务端会发送Server Key Exchange消息
        • DHE DSSDHE RSAECDHE ECDSAECDHE RSA
        • 上述密码套件都是使用临时DH/ECDH密码协商算法,客户端每次连接服务器的时候,服务器会发送动态DH信息,这些信息不存在服务端证书中,需要通过Server Key Exchange消息传递,传递的DH信息需要使用服务器的私钥进行签名,该私钥和证书中包含的服务器公钥是一对。
      • 下列的密钥套件,服务端也会发送Server Key Exchange消息
        • DH_anonECDH_anon
        • 使用的是静态DH/ECDH协商算法,但由于没有证书,所以需要Server Key Exchange消息传递相关DH信息,传递的DH消息需要使用服务器的私钥进行签名
      • 下列的密码套件不允许服务器发送Server Key Exchange消息
        • RSADH_DSSDH_RSA
        • 对于RSA密码套件,客户端计算出预备主密钥,然后使用服务器RSA公钥加密发送给服务端,服务端反解出预备主密钥即可,没有Server Key Exchange子消息也能完成密钥协商。
        • 对于DH_DSS/DH_RSA密钥套件,证书中已经包含静态DH信息,无须服务端额外发送Server Key Exchange子消息,客户端和服务端各协商出预备主密钥的一半密钥,结合起来就是预备主密钥。目前已经很少看到这样的密码套件,CA机构也不会在签发证书时包含静态DH信息。
    • [5] Certificate Request
      • 该消息表示想要收到客户端的证书,一般是双向认证时有该消息。
    • [6] Server Hello Done
      • 表示服务端发送了足够的消息,接下来等待和客户端协商出预备主密钥。
    • [7] Client Certificate
      • 发送客户端证书,一般是双向认证时会发送。
    • [8] Client Key Exchange
      • 消息结构
      •   struct {
          		select(KeyExchangeAlgorithm){
          			case rsa:
          				EncryptedPreMasterSecret;
          			case dhe_dss:
          			case dhe_rsa:
          			case df_dss:
          			case dh_rsa:
          			case dh_anon:
          				ClientDiffieHellmanPublic;
          			case ec_diffie)hellman:
          				ClientECHiffieHellmanPublic;
          		}exchange_keys;
          } ClientKeyExchange;
        
      • 针对不同的密码套件,该消息一般有三种处理逻辑
      • EncryptedPreMasterSecret
        • 如果 RSA算法用于身份验证和密钥交换,客户端会生成一个48字节的预备主密钥,然后用服务器证书中的公钥加密并发送给服务器端。最终发送的消息就是Encrypted PreMaster。
      • ClientDiffieHellmanPublic
        • 如果密码套件中密钥协商算法是 DH算法,客户端必须发送 DH公钥给服务器端。
      • ClientECDiffieHellmanPublic
        • 如果协商出的密码套件密钥协商算法是 ECDHE,客户端需要发送 ECDH公钥。
    • [9] 计算主密钥和密钥块
      • 计算预备主密钥,不同的密钥协商算法,计算方法不同。
      • RSA密钥协商算法
        • RSA密钥协商算法,生成预备主密钥比较简单,直接生成预备主密钥。
        • 然后使用服务端证书中的公钥加密预备主密钥,将加密后的预备主密钥发送给服务端。
        • 服务端接收到加密后的预备主密钥后,使用私钥解密,得到预备主密钥。
      • DH密钥协商算法
        • 服务器端生成DH参数和服务器DH密钥对,用RSA私钥签名DH参数和服务器DH公钥,最后将签名值、DH参数、服务器DH公钥发送给客户端。
        • 客户端通过服务器发送的证书中的RSA的公钥验证签名,获取到DH参数和服务器DH公钥。
        • 客户端通过DH参数生成客户端的DH密钥对,并将客户端DH公钥发送给服务器端。
        • 客户端通过客户端DH私钥和服务器端DH公钥计算出预备主密钥。
        • 服务器端接收到客户端的DH公钥,结合服务器的DH私钥计算出预备主密钥。
        • 最终客户端和服务器端计算出的预备主密钥能够保持一致。
      • 双方都拿到预备主密钥后,就可以根据以下公式计算出主密钥
      • master_secret = PRF(pre_master_secret, “master secret”, ClientHello.random + ServerHello.random)
      • 主密钥的长度固定是48字节。而预备主密钥的长度取决于密码套件算法,如果 RSA算法用来协商密钥,预备主密钥的长度是 48字节;如果 DH/ECDH算法用来协商密钥,长度取决于 DH /ECDH算法的公钥。
      • 计算出主密钥后,还需要根据主密钥计算出密钥块。密钥块主要有六个
      • Client MAC Key
      • Server MAC Key
      • Client Key
      • Server Key
      • Client IV
      • Server IV
      • MAC Key主要用于数据的完整性校验,Key用于加密数据。IV作为加密算法的初始化向量。
    • [10] Certificate verify
      • 证书验证。双向认证时有该消息,这个时候客户端已经把证书发送给服务端了,但客户端还要向服务器证明证书中对应的私钥的正确和自己是会话持有者。
    • [11] Change Cipher Spec
      • 通知对方,可以用协商好的密钥进行通信了。
    • [12] Finished [Encrypted Handshake Message]
      • 确认所有握手消息没有被篡改。

Nginx搭建HTTPS网站

  • 接下来用Nginx搭建一个HTTPS网站,实现SSL/TLS的双向认证。

  • 打开Nginx的配置文件/usr/local/nginx/conf/nginx.conf,HTTPS服务默认是注释的,去掉注释,并且需要再添加两个字段ssl_verify_clientssl_client_certificate

  •   # HTTPS server
      server {
      	listen       10088 ssl;
      	server_name  localhost;
    
      	# 服务端证书
      	ssl_certificate      server.crt;
      	# 服务端证书密钥
      	ssl_certificate_key  server.key;
    
      	ssl_session_cache    shared:SSL:1m;
      	ssl_session_timeout  5m;
      	
      	# 表示开启客户端证书校验
      	ssl_verify_client on;
      	# 放置CA证书
      	ssl_client_certificate ca.crt;
    
      	ssl_ciphers  HIGH:!aNULL:!MD5;
      	ssl_prefer_server_ciphers  on;
    
      	location / {
      		root   html;
      		index  index.html index.htm;
      	}
      }
    
  • 这里需要用到三张证书,CA证书,服务端证书和客户端证书,可以通过OpenSSL命令行工具来生成。

  • CA证书

    • 生成RSA私钥
    • openssl genrsa -out ca.key 2048
    • 生成CA证书
    • openssl req -new -x509 -key ca.key -out ca.crt -days 365
  • 服务端证书

    • 生成服务端密钥
    • openssl genrsa -out server.key 2048
    • 生成证书请求文件
    • openssl req -new -key server.key -out server.csr
    • 使用CA证书签发服务端证书
    • openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt -days 365
  • 客户端证书

    • 生成客户端密钥
    • openssl genrsa -out client.key 2048
    • 生成证书请求文件
    • openssl req -new -key client.key -out client.csr
    • 使用CA证书签发客户端证书
    • openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out client.crt -days 365
    • 将客户端证书和私钥合并成pfx证书
    • openssl pkcs12 -export -in client.crt -inkey client.key -out client.pfx
  • 服务端证书以及私钥和CA证书生成后,放到Nginx配置文件所在目录下,然后将客户端的pfx证书拷贝到windows平台下,打开Edge浏览器的设置界面,在隐私、搜索和服务栏找到管理证书,然后把刚才的client.pfx证书导入即可。这里注意下,导入后要关掉浏览器重新打开。
    在这里插入图片描述
    在这里插入图片描述

  • 然后去访问对应https网站,浏览器会弹出对话框,让我们选择对应的客户端证书。只有选择证书并确认后,才可以成功访问到对应的https网站。没有客户端证书或者未成功选择证书,都是无法访问的。如果是单向认证的话,就不需要客户端证书了。
    在这里插入图片描述

WireShark抓包分析SSL/TLS握手过程

  • 接下来就用WireShark抓包工具详细分析SSL/TLS双向认证的握手过程。

  • 先看下整体流程,抓包可以看到,在进行SSL/TLS握手前,先要进行TCP的三次握手,建立连接。关于TCP的握手过程,这里就不介绍了,可参考我的这一篇文章 抓包分析TCP协议
    在这里插入图片描述

  • 接下来对SSL/TLS握手的每条信息,详细看一下

  • Client Hello

    • Client Hello消息中有TLS版本号,客户端生成的随机数,以及客户端支持的密码套件等信息。
      在这里插入图片描述
  • Server Hello

    • Client Hello消息中有TLS版本号,服务端生成的随机数,以及服务端最终确认要使用的密码套件等信息。
      在这里插入图片描述
  • Server Certificate

    • 服务端发送自己的证书
      在这里插入图片描述
  • Server Key Exchange
    在这里插入图片描述

  • Certificate Request

    • 表示服务端想要收到客户端的证书
      在这里插入图片描述
  • Server Hello Done

    • 服务端请求结束
      在这里插入图片描述
  • Client Certificate

    • 客户端发送自己的证书
      在这里插入图片描述
  • Client Key ExChange

    • 上面选择的加密套件是 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,密钥协商算法是ECDHE,因此这里发送的消息是ClientECDiffieHellmanPublic
      在这里插入图片描述
    • 如果选择的加密套件密钥协商算法为RSA,比如 TLS_RSA_WITH_AES_128_GCM_SHA256 加密套件,则对应发送的消息就为 EncryptedPreMasterSecret。
      在这里插入图片描述
  • Certificate Verify

    • 客户端证书验证
      在这里插入图片描述
  • Change Cipher Spec

    • 通知对方,可以用协商好的密钥进行通信了。
      在这里插入图片描述
  • Finished [Encrypted Handshake Message]

    • 密钥协商完成
      在这里插入图片描述
  • Application Data

    • 用协商好的密钥进行加密通信
      在这里插入图片描述
  • 这就是整个SSL/TLS协议握手的过程。

  • 上面展示的是SSL/TLS双向认证的过程,可以关掉Nginx对客户端的证书校验,实现单向认证。
    在这里插入图片描述

  • 这是单向认证时抓的包,可以与上面的双向认证比对下,主要少了服务端请求客户端发送证书的消息Certificate Request,客户端发送证书消息Client Certificate,客户端证书校验消息Certificate verify。其他流程和双向认证是一样的。

C/C++代码实现SSL/TLS通信

  • 我们还可以使用C/C++代码来实现SSL/TLS的通信
  • 服务端代码
    •   #include <stdio.h>
        #include <stdlib.h>
        #include <memory.h>
        #include <errno.h>
        #include <sys/types.h>
        #include <sys/socket.h>
        #include <netinet/in.h>
        #include <arpa/inet.h>
        #include <unistd.h>
        #include <openssl/rsa.h>     
        #include <openssl/crypto.h>
        #include <openssl/x509.h>
        #include <openssl/pem.h>
        #include <openssl/ssl.h>
        #include <openssl/err.h>
        #include <openssl/rand.h>
      
        #define CERTF   "server.crt" /*服务端的证书(需经CA签名)*/
        #define KEYF   "server.key"  /*服务端的私钥(建议加密存储)*/
        #define CACERT "ca.crt" /*CA 的证书*/
        #define PORT   10088   /*准备绑定的端口*/
      
        int main (){
            SSL_load_error_strings();            /*为打印调试信息作准备*/
            OpenSSL_add_ssl_algorithms();        /*初始化*/
      
            SSL_CTX* ctx = SSL_CTX_new(TLSv1_server_method());
            if(ctx == NULL) {
                printf("SSL_CTX_new failed.\n");
                return -1;
            }
      
            SSL_CTX_set_verify(ctx,SSL_VERIFY_PEER,NULL);   /*是否验证客户端证书,双向认证时开启*/
            SSL_CTX_load_verify_locations(ctx,CACERT,NULL); /*若验证,则放置CA证书*/
      
            if (SSL_CTX_use_certificate_file(ctx, CERTF, SSL_FILETYPE_PEM) <= 0) {
                ERR_print_errors_fp(stderr);
                return -1;
            }
      
            if (SSL_CTX_use_PrivateKey_file(ctx, KEYF, SSL_FILETYPE_PEM) <= 0) {
                ERR_print_errors_fp(stderr);
                return -1;
            }
      
            if (!SSL_CTX_check_private_key(ctx)) {
                printf("Private key does not match the certificate public key\n");
                return -1;
            }
      
            SSL_CTX_set_cipher_list(ctx,"RC4-MD5"); 
      
            /*开始正常的TCP socket过程.*/
            printf("Begin TCP socket...\n");
      
            int listenSock = socket(AF_INET, SOCK_STREAM, 0);  
            if(listenSock == -1){
                perror("socket");
                return -1;
            }
      
            struct sockaddr_in sa_serv;
            memset (&sa_serv, 0, sizeof(sa_serv));
            sa_serv.sin_family = AF_INET;
            sa_serv.sin_addr.s_addr = INADDR_ANY;
            sa_serv.sin_port = htons(PORT);         
      
            if(bind(listenSock, (struct sockaddr*) &sa_serv, sizeof (sa_serv)) == -1){
                perror("bind");
                return -1;
            }
      
            /*接受TCP链接*/
            if(listen (listenSock, 5) == -1){
                perror("listen");
                return -1;
            }                   
      
            struct sockaddr_in sa_cli;
            socklen_t client_len = sizeof(sa_cli);
            int connfd = accept (listenSock, (struct sockaddr*) &sa_cli, &client_len);
            if(connfd == -1){
                perror("accept");
                close (listenSock);
                return -1;
            }
      
            printf ("[%s:%d] connected...\n", inet_ntoa(sa_cli.sin_addr), sa_cli.sin_port);
      
            /*TCP连接已建立,进行服务端的SSL过程. */
            printf("Begin server side SSL\n");
      
            SSL* ssl = SSL_new (ctx);
            if(ssl == NULL){
                printf("SSL_new failed.\n");
                return -1;
            }
      
            SSL_set_fd (ssl, connfd);
            
            int sslSock = SSL_accept (ssl);
            if(sslSock == -1){
                ERR_print_errors_fp(stderr);
                return -1;
            }
      
            printf("SSL_accept finished\n");
      
            /*打印所有加密算法的信息(可选)*/
            printf ("SSL connection using %s\n", SSL_get_cipher(ssl));
      
            /*得到客户端的证书并打印些信息(可选) */
            X509* client_cert = SSL_get_peer_certificate (ssl);
            if (client_cert != NULL) {
                printf ("Client certificate:\n");
      
                char* subStr = X509_NAME_oneline(X509_get_subject_name (client_cert), 0, 0);
                if(subStr == NULL){
                printf("X509_NAME_oneline subject failed.\n");
                return -1;
                }
      
                printf ("subject: %s\n", subStr);
                //Free (subStr);
      
                char* issStr = X509_NAME_oneline(X509_get_issuer_name  (client_cert), 0, 0);
                if(issStr == NULL){
                printf("X509_NAME_oneline subject failed.\n");
                return -1;
                }
      
                printf ("issuer: %s\n", issStr);
                //Free (issStr);
      
                X509_free (client_cert);/*如不再需要,需将证书释放 */
            }else{
                printf ("Client does not have certificate\n");
            }
                
            char buf[4096] = {0};  
            /* 数据交换开始,用SSL_write,SSL_read代替write,read */
            int readSize = SSL_read(ssl, buf, sizeof(buf) - 1);  
            if(readSize == -1){
                ERR_print_errors_fp(stderr);
                return -1;
            }
      
            printf ("SSL_read buf[%d] = {%s}\n", readSize, buf);
      
            if(SSL_write (ssl, "Welcome to Connect to Server!", strlen("Welcome to Connect to Server!")) == -1){
                ERR_print_errors_fp(stderr);
                return -1;
            } 
      
            shutdown (connfd, 2);
            SSL_free (ssl);
            SSL_CTX_free (ctx);
            return 0;
        }
      
  • 客户端代码
    •   #include <stdio.h>
        #include <stdlib.h>
        #include <memory.h>
        #include <errno.h>
        #include <sys/types.h>
        #include <sys/socket.h>
        #include <netinet/in.h>
        #include <arpa/inet.h>
        #include <unistd.h>
        #include <openssl/rsa.h>     
        #include <openssl/crypto.h>
        #include <openssl/x509.h>
        #include <openssl/pem.h>
        #include <openssl/ssl.h>
        #include <openssl/err.h>
        #include <openssl/rand.h>
      
        /*所有需要的参数信息都在此处以#define的形式提供*/
        #define CERTF  "client.crt"  /*客户端的证书(需经CA签名)*/
        #define KEYF  "client.key"   /*客户端的私钥(建议加密存储)*/
        #define CACERT "ca.crt"      /*CA 的证书*/
        #define PORT   10088          /*服务端的端口*/
        #define SERVER_ADDR "127.0.0.1"  /*服务段的IP地址*/
      
        int main () {
            /*初始化*/
            OpenSSL_add_ssl_algorithms(); 
      
            //载入所有SSL错误消息
            SSL_load_error_strings();     
      
            /*采用什么协议(SSLv2/SSLv3/TLSv1)在此指定*/
            /*申请SSL会话环境*/
            SSL_CTX *ctx = SSL_CTX_new(TLSv1_client_method());
            if(ctx == NULL){
                printf("SSL_CTX_new failed!\n");
                return -1;
            }                       
            
            /*是否验证服务端证书*/
            SSL_CTX_set_verify(ctx,SSL_VERIFY_PEER,NULL);
      
            /*若验证对方,则放置CA证书*/
            SSL_CTX_load_verify_locations(ctx,CACERT,NULL); 
      
            /*加载自己的证书*/
            if (SSL_CTX_use_certificate_file(ctx, CERTF, SSL_FILETYPE_PEM) <= 0) {
                ERR_print_errors_fp(stderr);
                return -1;
            }
            
            /*加载自己的私钥,以用于签名*/
            if (SSL_CTX_use_PrivateKey_file(ctx, KEYF, SSL_FILETYPE_PEM) <= 0) {
                ERR_print_errors_fp(stderr);
                return -1;
            }
      
            /*调用了以上两个函数后,检验一下自己的证书与私钥是否配对*/
            if (!SSL_CTX_check_private_key(ctx)) {
                printf("Private key does not match the certificate public key\n");
                return -1;
            } 
      
            /*以下是正常的TCP socket建立过程*/
            printf("Begin tcp socket...\n");
      
            int sock = socket(AF_INET, SOCK_STREAM, 0);
            if(sock == -1){
                perror("socket");
                return -1;
            }       
      
            struct sockaddr_in sa;
            memset (&sa, 0, sizeof(sa));
            sa.sin_family = AF_INET;
            sa.sin_addr.s_addr = inet_addr(SERVER_ADDR);   /* Server IP */
            sa.sin_port = htons(PORT);          /* Server Port number */
      
            if(connect(sock, (struct sockaddr*) &sa, sizeof(sa)) == -1){
                perror("connect");
                return -1;
            } 
      
            /* TCP 链接已建立.开始 SSL 握手过程 */
            printf("Begin SSL negotiation \n");
      
            /*申请一个SSL套接字*/
            SSL* ssl = SSL_new (ctx);
            if(ssl == NULL){
                printf("SSL_new failed.\n");
                return -1;
            }
      
            /*绑定读写套接字*/
            SSL_set_fd(ssl, sock);
      
            if(SSL_connect(ssl) == -1){
                ERR_print_errors_fp(stderr);
                return -1;
            }
      
            /*打印所有加密算法的信息(可选)*/
            printf ("SSL connection using %s\n", SSL_get_cipher(ssl));
      
            /*得到服务端的证书并打印些信息(可选) */
            X509* server_cert = SSL_get_peer_certificate (ssl); 
            if(server_cert == NULL){
                printf("SSL_get_peer_certificate failed.\n");
                return -1;
            }     
            
            printf ("Server certificate:\n");
      
            char* subStr = X509_NAME_oneline(X509_get_subject_name (server_cert),0,0);
            if(subStr == NULL){
                printf("X509_NAME_oneline subject failed.\n");
                return -1;
            }
      
            printf("subject: %s\n", subStr);
            // Free(subStr);
      
            char* issStr = X509_NAME_oneline (X509_get_issuer_name(server_cert),0,0);
            if(issStr == NULL){
                printf("X509_NAME_oneline issuer failed.\n");
                return -1;
            }
      
            printf ("issuer: %s\n", issStr);
            // Free (issStr);
      
            X509_free(server_cert);  /*如不再需要,需将证书释放 */
      
            /* 数据交换开始,用SSL_write,SSL_read代替write,read */
            printf("Begin SSL data exchange\n");
      
            if(SSL_write(ssl, "Hello, I am client!", strlen("Hello, I am client!")) == -1){
                ERR_print_errors_fp(stderr);
                return -1;
            } 
      
            char buf[4096] = {0};
            int readSize = SSL_read(ssl, buf, sizeof(buf) - 1); 
            if(readSize == -1){
                ERR_print_errors_fp(stderr);
                return -1;
            }
      
            printf ("SSL_read buf[%d] = {%s}\n", readSize, buf);
      
            SSL_shutdown (ssl);  /* send SSL/TLS close_notify */
      
            shutdown (sock, 2);
            SSL_free (ssl);
            SSL_CTX_free (ctx);
      
            return 0;
        }
      
  • Makefile
    •   all: server client
        server: server.cpp
            g++ -o server server.cpp -lssl -lcrypto
        client: client.cpp
            g++ -o client client.cpp -lssl -lcrypto
      
        clean:
            rm server client
      

参考资料

  • 《HTTPS权威指南》
  • 《深入浅出HTTPS从原理到实战》
  • 《图解密码技术》
SSL/TLS协议
phoenix7670的博客
10-11 2290
SSL被设计用来使用TCP提供一个可靠的端到端安全服务,为两个通讯个体之间提供保密性和完整性(身份鉴别)第四步, 加密, 可供选择的加密算法[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传。第三步,MAC 计算:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传。​ 交换Hello消息,包括协议版本、会话ID、密码套件、压缩算法、初始随机数等;​ 服务器发送证书,交换密钥并请求证书;上层:SSL握手协议SSL改变加密规格协议SSL报警协议
深入解析SSL/TLS协议:原理、报文格式与抓包分析
qq_44103359的博客
05-16 659
Wireshark是一个流行的网络协议分析工具,可以捕获和显示网络上传输的数据包。
应用篇——SSLTLS
锦瑟常思的博客
01-17 1484
  目录 一、客户端与服务端的通信 二、SSLTLS 1)SSL(安全套接层协议): SSL协议提供的服务主要有: SSL协议的工作流程: 2)TLS(Transport Layer Security Protocol):安全传输层协议 TLS 记录协议提供的连接安全性具有两个基本特性:    TLS 握手协议提供的连接安全具有三个基本属性:    3)协议结构 TLS记录...
什么是HTTPS加密协议HTTPS安全传输原理,SSLTLS介绍,NGINX如何配置SSL证书
最新发布
Innocence_0的博客
08-18 1001
HTTPS是超文本传输协议HTTP)的安全版本。它使用SSL(安全套接层)或TLS(传输层安全)加密协议来保护数据传输的安全性和机密性,以防止未经授权的访问和窃听。HTTPS协议通常用于处理敏感信息,如在线支付或登录凭证等。可以通过URL的前缀来识别一个网站是否使用了HTTPS协议,即使用了“https://”前缀而不是“http://”。
协议森林17 我和你的悄悄话 (SSL/TLS协议)
weixin_34228662的博客
10-08 121
作者:Vamei 出处:http://www.cnblogs.com/vamei 严禁任何形式转载。   TLS名为传输层安全协议(Transport Layer Security Protocol),这个协议是一套加密通信协议。它的前身是SSL协议(安全套接层协议,Secure Sockets Layer)。这两个协议的工作方式类似,但TLS协议针对SSL协议进行了一些改善。SSL/TLS...
理解SSL/TLS协议
weixin_30384217的博客
02-25 162
理解SSL/TLS协议 背景 早期我们在访问web时使用HTTP协议,该协议在传输数据时使用明文传输,明文传输带来了以下风险:   1、信息窃听风险,第三方可以获取通信内容   2、信息篡改风险,第三方可以篡改通信内容   3、身份冒充风险,第三方可以冒充他人身份参与通信   为了解决明文传输所带来的风险,网景公司在1994年设计了SSL用于Web的安全传输协议,这是SSL的起源...
SSl(Secure Sockets Layer)
02-06 695
SSL 的英文全称是 “Secure Sockets Layer” ,中文名为 “ 安全套接层协议层 ” ,它是网景( Netscape )公司提出的基于 WEB 应用的安全协议SSL 协议指定了一种在应用程序协议(如 HTTP 、 Telenet 、 NMTP 和 FTP 等)和 TCP/IP 协议之间提供数据安全性分层的机制,它为 TCP/IP 连接提供数据加密、服务器认证、消息完整性以及
基于SSL/TLS协议的FTP客户端和服务器端
06-15
为了解决这个问题,SSL(Secure Socket Layer)和TLS(Transport Layer Security)协议应运而生,它们为网络通信提供了加密和身份验证机制。本项目就是基于这些协议,设计并实现了支持三元组认证的FTP系统。 **SSL/...
tls.rar_ tls protocol_TLS_ssl_ssl/tls_tls pdf
09-19
1. **TLS协议**:TLS是互联网上用于加密通信协议,它的主要目的是确保网络数据传输的安全性。它在HTTP基础上构建了HTTPS,提供了数据的加密、服务器身份验证和消息完整性检查。 2. **SSL协议**:SSLTLS的前身...
HTTPS的传输流程是什么?SSL/TLS详细流程
Burnup_110的博客
07-04 1392
HTTPS的传输流程是什么? 基础概念名词抢先了解 HTTPSHTTPS是在HTTP上建立SSL加密层,并对传输数据进行加密,是HTTP协议的安全版。 说得再简单一点,HTTPS就是 HTTP + SSL。 **SSL:**Secure Sockets Layer,即“安全套接层”。发明SSL协议的初衷,是为了解决HTTP明文传输不安全的问题。HTTP是应用层协议,是和TCP进行直接通信的,但是当我们将它转换成为HTTPS的时候,可以看下面这个流程,在HTTPS和TCP中间多了一个SSL层,这也就解释了
SSL/TLS的Heartbeat 扩展
liuxb1223的专栏
06-27 4287
本文主要从下面几个点讲解: 1、Heartbleed漏洞及漏洞发生的原因 2、SSL/TLS/DTLS协议简单的认识 3、TLS的扩展Heartbeat协议认识 4、heartbeat协议实现代码解读 5、实现一个网站支持SSL协议(生成一个伪证书)       1、Heartbleed漏洞及漏洞发生的原因   Heartbleed漏洞藏身于OpenSSLTLS H
SSL/TLS加密技术:保护网络通信安全的关键技术
Jerry_zpon的博客
03-06 4095
SSL(Secure Sockets Layer,安全套接字层)和TLS(Transport Layer Security,传输层安全)都是一种用于保护网络通信安全的协议SSLTLS的前身,目前TLS已经成为主流。SSL/TLS协议可以在浏览器和Web服务器之间建立安全通信通道,确保数据在传输过程中的保密性、完整性和真实性。在SSL/TLS加密技术中,使用了一种称为“加密算法”的技术,它可以将发送和接收的数据加密,并在数据传输过程中保持数据的安全。
SSLTLS协议
瞧字不识
11-07 2666
SSL (Secure Socket Layer) 为Netscape所研发,用以保障在Internet上数据传输之安全,利用数据加密(Encryption)技术,可确保数据在网络上之传输过程中不会被截取及窃听。目前一般通用之规格为40 bit之安全标准,美国则已推出128 bit之更高安全标准,但限制出境。 只要3.0版本以上之I.E.或Netscape浏览器即可支持SSL。 当前版本为3.
写文章

热门文章

  • 对称加密与非对称加密算法 37409
  • git pull时报错:Your local changes to the following files would be overwritten by merge 33176
  • PR视频剪辑软件教程 32714
  • 使用Wireshark抓包分析TCP协议 24479
  • QT之QTableWidget控件 23925

分类专栏

  • 安全 付费 11篇
  • 网络协议 10篇
  • 实用框架 12篇
  • 逆向分析 2篇
  • 网络安全 18篇
  • 开发语言 55篇
  • C/C++开发 27篇
  • cmake 8篇
  • QT 17篇
  • MFC 3篇
  • 软件打包 10篇
  • 视频动画 7篇
  • 操作系统 8篇
  • git 12篇
  • opencv 2篇

最新评论

  • 构建网络信息安全的中国方案 - 国密SSL/TLCP协议介绍以及国密Nginx服务器部署

    努力学习德小白: 那大佬还有没有浏览器支持ECC_SM4_GCM_SM3这个密码套件的可以分享一下吗

  • 构建网络信息安全的中国方案 - 国密SSL/TLCP协议介绍以及国密Nginx服务器部署

    努力学习德小白: 那应该是不支持了,我看加密套件里面只有0xe013这个套件

  • 构建网络信息安全的中国方案 - 国密SSL/TLCP协议介绍以及国密Nginx服务器部署

    大草原的小灰灰: 抓包看下浏览器的加密套件列表都有什么,nginx必须支持。ECC_SM4_SM3这个加密套件目前好像不支持了,看浏览器有没有ECC_SM4_GCM_SM3这个加密套件,也就是0xe053。我当时使用奇安信浏览器用的就是这个加密套件。

  • 构建网络信息安全的中国方案 - 国密SSL/TLCP协议介绍以及国密Nginx服务器部署

    努力学习德小白: 但是浏览器访问我的虚拟机也显示,使用了不支持的协议,该如何解决这个问题,大佬有方法吗

  • 构建网络信息安全的中国方案 - 国密SSL/TLCP协议介绍以及国密Nginx服务器部署

    努力学习德小白: 我浏览器用的就是文章中介绍的那个,但是你那个链接的浏览器好像协议过期了,我直接走官网下载的,在连接的时候还是告诉选择了不支持的协议,我用抓包软件抓去了一下看到浏览器发送的GMSSLv1协议里面的套件是ECC_SM4_SM3,我知道这个是sm2协议的套件,但是我看文章内容里面的套件配置是 ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:AES128-SHA:DES-CBC3-SHA:ECC-SM4-CBC-SM3:ECC-SM4-GCM-SM3; 会不会是因为中间的这些差别所以导致的问题,我也尝试直接把ECC_SM4_SM3这个加入到conf套件里面,仍然有问题,请大佬指点

最新文章

  • C/C++二维码生成库qrencode编译与使用
  • Qt实现json数据的生成、解析、修改和删除
  • makefile实现大型项目编译部署
2024
08月 4篇
07月 5篇
06月 7篇
05月 6篇
04月 7篇
03月 5篇
02月 2篇
01月 6篇
2023年47篇
2022年44篇
2021年15篇

目录

目录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大草原的小灰灰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或 充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值

深圳SEO优化公司网站关键词优化效果图贵阳市网站优化平台沈阳网站seo优化方案镇江网站排名优化公司从化公司网站优化推广平台放心的企业网站优化公司普陀区专业网站优化价格网站优化被骗了怎么办昌平优化网站排名郑州网站优化品牌夏邑专业网站优化报价35类网站流量优化网站导航怎么做优化网站优化公司如何群力优化网站电话淮安网站排名优化软件汕尾便捷的免费网站优化网站优化推广seo晋州网站优化电话深圳搜索引擎网站优化多少钱沧州网站优化排名价格沧州网站建设和优化沁阳网站排名优化方案延庆网站推广优化排名济南五金行业网站优化推广渠道网站优化指数词排名无锡营销网站建设优化武汉网站优化推广指南太原优化网站排名网站怎么优化收录块歼20紧急升空逼退外机英媒称团队夜以继日筹划王妃复出草木蔓发 春山在望成都发生巨响 当地回应60岁老人炒菠菜未焯水致肾病恶化男子涉嫌走私被判11年却一天牢没坐劳斯莱斯右转逼停直行车网传落水者说“没让你救”系谣言广东通报13岁男孩性侵女童不予立案贵州小伙回应在美国卖三蹦子火了淀粉肠小王子日销售额涨超10倍有个姐真把千机伞做出来了近3万元金手镯仅含足金十克呼北高速交通事故已致14人死亡杨洋拄拐现身医院国产伟哥去年销售近13亿男子给前妻转账 现任妻子起诉要回新基金只募集到26元还是员工自购男孩疑遭霸凌 家长讨说法被踢出群充个话费竟沦为间接洗钱工具新的一天从800个哈欠开始单亲妈妈陷入热恋 14岁儿子报警#春分立蛋大挑战#中国投资客涌入日本东京买房两大学生合买彩票中奖一人不认账新加坡主帅:唯一目标击败中国队月嫂回应掌掴婴儿是在赶虫子19岁小伙救下5人后溺亡 多方发声清明节放假3天调休1天张家界的山上“长”满了韩国人?开封王婆为何火了主播靠辱骂母亲走红被批捕封号代拍被何赛飞拿着魔杖追着打阿根廷将发行1万与2万面值的纸币库克现身上海为江西彩礼“减负”的“试婚人”因自嘲式简历走红的教授更新简介殡仪馆花卉高于市场价3倍还重复用网友称在豆瓣酱里吃出老鼠头315晚会后胖东来又人满为患了网友建议重庆地铁不准乘客携带菜筐特朗普谈“凯特王妃P图照”罗斯否认插足凯特王妃婚姻青海通报栏杆断裂小学生跌落住进ICU恒大被罚41.75亿到底怎么缴湖南一县政协主席疑涉刑案被控制茶百道就改标签日期致歉王树国3次鞠躬告别西交大师生张立群任西安交通大学校长杨倩无缘巴黎奥运

深圳SEO优化公司 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化