Openssl 之 SSL 协议通信

Openssl 之 SSL 协议通信_第1张图片
ssl.jpg

0x00 前言

SSL协议最早由netscape公司提出,包含ssl v2 和 v3 两个版本。主要目的是保证通信双方的信道安全。它能够提供数据加密、身份认证以及消息完整性保护,另外SSL协议还支持数据压缩。SSL协议通过客户端和服务器端握手来协商各种算法和密钥。

Openssl是一个功能强大的开源的密码算法和协议的工具箱。主要提供的功能有: SSL协议实现(包括SSL V2, SSL V3 和 TLS V1),对称密码算法(AES,DES,Blowfish,Camellia等),哈希算法(MD5,SHA1等),公钥密码算法(RSA,DH,DSA,ECC,ECDH,ECDSA)以及证书相关操作等。

0x01 服务端


  1. SSL初始化操作

     SSL_library_init()      
     OpenSSL_add_all_algorithms() /* 载入Openssl所支持的算法 */
     SSL_load_error_strings() /* 载入Openssl的相关错误信息 */
    
  2. 申请SSL_CTX数据结构

     SSL_CTX * ctx = SSL_CTX_new(SSLv23_server_method())
    

    SSLv23_server_method() 表明是以SSL v2 和 v3 标准兼容方式产生SSL_CTX, 即 SSL Context Text,也可以使用 SSLv2_server_method()SSLv3_server_method() 单独表示v2 或 v3标准。

  3. 服务端载入自己的证书

     #define CACERT     ".\\cert\\server\\server-cert.crt" 
     SSL_CTX_use_certificate_file(ctx, CACERT, SSL_FILETYPE_PEM)
    

server-cert.crt 是服务端的数字证书,由CA机构认证签发。此证书用来发送给客户端,证书内包含有服务端的公钥。

  1. 服务端载入自己的私钥并检查

     #define   PRIKEY ".\\cert\\server\\server-key.pem"
     SSL_CTX_use_PrivateKey_file(ctx, PRIKEY, SSL_FILETYPE_PEM)
     SSL_CTX_check_private_key(ctx)   /*检查服务端的私钥是否正确*/
    

    server-key.pem 是 服务端的私钥文件,里面包含密钥信息,是通过openssl的命令行工具生成,详细信息参见openssl相关文档。

  2. 建立socket通信

     WSADATA wsaData;
     WSAStartup( MAKEWORD(2, 2), &wsaData )
     sockfd = socket(PF_INET, SOCK_STREAM, 0)) /* 建立 socket 结构 */
     bind(sockfd, (struct sockaddr *) &my_addr, sizeof(struct sockaddr)) /* 绑定地址 */
     listen(sockfd, 2) /* 监听 */
     new_fd =accept(sockfd, (struct sockaddr *) &their_addr,&len)) /* 等待客户端连接 */
    
  3. 建立SSL连接

     SSL *ssl = SSL_new(ctx) /* 基于上述SSL_CTX的句柄ctx产生一个新的 SSL 用于通信 */
     SSL_set_fd(ssl, new_fd) /* 将刚刚接收到的客户端连接的socket加入到 SSL 结构中 */
     SSL_accept(ssl)     /* 建立 SSL 连接 */
    
  4. 基于SSL的数据通信

     SSL_write(ssl, buf, strlen(buf)) /* 向客户端发送消息,消息的传输通过SSL加密 */ 
     SSL_read(ssl, buf, MAXBUF)      /* 接收客户端发送来的消息 */
    
  5. 关闭与释放

     SSL_shutdown(ssl) /* 关闭 SSL 连接 */ 
     SSL_free(ssl)   /* 释放 SSL */     
     closesocket(new_fd) /* 关闭 客户端连接的 socket */
     closesocket(sockfd) /* 关闭监听的 socket */
     SSL_CTX_free(ctx) /* 释放 CTX */
    

0x02 客户端


  1. SSL初始化操作

     /* 参见 服务端代码 */
     SSL_library_init()      
     OpenSSL_add_all_algorithms() 
     SSL_load_error_strings() 
    
  2. 申请SSL_CTX数据结构

     SSL_CTX * ctx = SSL_CTX_new(SSLv23_server_method())
    
  3. 建立socket通信

     WSADATA wsaData;
     WSAStartup( MAKEWORD(2, 2), &wsaData )      
     sockfd = socket(AF_INET, SOCK_STREAM, 0)
     connect(sockfd, (struct sockaddr *) &dest, sizeof(dest))/* 连接到服务器 */
     /* dest 是 服务器端的 地址信息 和 端口信息 */
    
  4. 建立SSL连接

     SSL *ssl = SSL_new(ctx)
     SSL_set_fd(ssl, sockfd) /* 将连接到服务端的socket加入到SSL结构中*/
     SSL_connect(ssl)    /* 与服务端建立SSL连接 */
    

    与服务端成功建立SSL连接后,客户端可以通过 SSL_get_peer_certificate(ssl) 获取到服务端的证书,从而进一步获取证书内的详细信息,如获取证书的颁发者 X509_get_issuer_name(cert) ,更多信息参见openssl提供的x509证书机制。

  5. 基于SSL的数据通信

     SSL_read(ssl, buffer, MAXBUF) /* 接收服务器发来的信息 */
     SSL_write(ssl, buffer, strlen(buffer)) /* 向服务器发送信息 */
    

    SSL_read & SSL_write 建立在SSL基础上,所以客户端与服务端的通信数据是受加密保护的。

  6. 关闭连接

     SSL_shutdown(ssl);
     SSL_free(ssl);
     closesocket(sockfd);
     SSL_CTX_free(ctx);
    

0x03 总结


SSL协议,将数据加密技术集成到了协议自身,数据在离开计算机前就已经被加密保护,只有到达通信对方后才能被解密。openssl提供的证书和密码学算法支撑起SSL协议的运转。

理论上,即使加密的数据在到达对方目标之前,存在中间人的窃听或截取,被加密的数据仍然不可能被破解。然而,随着计算机技术的变化和密码翻译技术的发展,SSL中的加密协议也面临着新的考验。

你可能感兴趣的:(Openssl 之 SSL 协议通信)