Linux基础(18)HTTPS编程

中间代理服务器: 存在于外部网络和内部服务器之间  代理服务器一般有两个用途: 负载均衡防火墙

负载均衡:(Load Balance)  百科的解释

  其含义就是指将负载(工作任务)进行平衡、分摊到多个操作单元上进行运行,例如FTP服务器、Web服务器、企业核心应用服务器和其它主要任务服务器等,从而协同完成工作任务。负载均衡构建在原有网络结构之上,它提供了一种透明且廉价有效的方法扩展服务器和网络设备的带宽、加强网络数据处理能力、增加吞吐量、提高网络的可用性和灵活性。

  软件负载均衡: 指在一台或多台服务器相应的操作系统上安装一个或多个附加软件来实现负载均衡,如DNS Load Balance,CheckPoint Firewall-1 ConnectControl等,它的优点是基于特定环境,配置简单,使用灵活,成本低廉,可以满足一般的负载均衡需求。

  硬件负载均衡:  是直接在服务器和外部网络间安装负载均衡设备,这种设备通常称之为负载均衡器,由于专门的设备完成专门的任务,独立于操作系统,整体性能得到大量提高,加上多样化的负载均衡策略,智能化的流量管理,可达到最佳的负载均衡需求。

  负载均衡器有多种多样的形式,除了作为独立意义上的负载均衡器外,有些负载均衡器集成在交换设备中,置于服务器与Internet链接之间,有些则以两块网络适配器将这一功能集成到PC中,一块连接到Internet上,一块连接到后端服务器群的内部网络上。一般而言,硬件负载均衡在功能、性能上优于软件方式,不过成本昂贵。

防火墙:  百科的解释

  当代理服务器收到客户端的HTTPS请求时,先核实请求然后再转发个内部服务器 ,

QOS(Quality of Service,服务质量):  https://baike.baidu.com/item/qos/404053?fr=aladdin

  指一个网络能够利用各种基础技术,为指定的网络通信提供更好的服务能力,是网络的一种安全机制, 是用来解决网络延迟和阻塞等问题的一种技术。QoS的保证对于容量有限的网络来说是十分重要的,特别是对于流多媒体应用,例如VoIP和IPTV等,因为这些应用常常需要固定的传输率,对延时也比较敏感。

  当网络发生拥塞的时候,所有的数据流都有可能被丢弃;为满足用户对不同应用不同服务质量的要求,就需要网络能根据用户的要求分配和调度资源,对不同的数据流提供不同的服务质量:对实时性强且重要的数据报文优先处理;对于实时性不强的普通数据报文,提供较低的处理优先级,网络拥塞时甚至丢弃。QoS应运而生。

CA: 证书签发机构, 全球CA认证服务市场分额划分 :三大巨头——Verisign、Thawte、GeoTrust主导

CA证书: 是CA机构颁发的证书  转自: https://www.jianshu.com/p/950ffeb370db

    CA证书也就我们常说的数字证书,包含证书拥有者的身份信息,CA机构的签名,公钥和私钥。身份信息用于证明证书持有者的身份;CA签名用于保证身份的真实性;公钥和私钥用于通信过程中加解密,从而保证通讯信息的安全性。
根证书和中间证书的区别 : http://blog.sina.com.cn/s/blog_5fa211b40102xhat.html

SSL的使用:  #include <openssl/ssl.h>
  1.初始化SSL
    int SSL_library_init(void);        在使用SSL前必须初始化SSL
    #define OpenSSL_add_all_algorithms(); 载入所有SSL的加密算法
    void SSL_load_error_string();       载入所有SSL的错误消息
    const SSL_METHOD *ssl_method = SSLv23_server_method();  指定服务器本次会话的协议版
#define SSLv23_method           TLS_method
#define SSLv23_server_method    TLS_server_method
#define SSLv23_client_method    TLS_client_method


/* Negotiate highest available SSL/TLS version */
__owur const SSL_METHOD *TLS_method(void);
__owur const SSL_METHOD *TLS_server_method(void);
__owur const SSL_METHOD *TLS_client_method(void);


# ifndef OPENSSL_NO_TLS1_METHOD
DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *TLSv1_method(void)) /* TLSv1.0 */
DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *TLSv1_server_method(void)) /* TLSv1.0 */
DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *TLSv1_client_method(void)) /* TLSv1.0 */
# endif


# ifndef OPENSSL_NO_TLS1_1_METHOD
DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *TLSv1_1_method(void)) /* TLSv1.1 */
DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *TLSv1_1_server_method(void)) /* TLSv1.1 */
DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *TLSv1_1_client_method(void)) /* TLSv1.1 */
# endif


# ifndef OPENSSL_NO_TLS1_2_METHOD
DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *TLSv1_2_method(void)) /* TLSv1.2 */
DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *TLSv1_2_server_method(void)) /* TLSv1.2 */
DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *TLSv1_2_client_method(void)) /* TLSv1.2 */
# endif


# ifndef OPENSSL_NO_DTLS1_METHOD
DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *DTLSv1_method(void)) /* DTLSv1.0 */
DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *DTLSv1_server_method(void)) /* DTLSv1.0 */
DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *DTLSv1_client_method(void)) /* DTLSv1.0 */
# endif


# ifndef OPENSSL_NO_DTLS1_2_METHOD
DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *DTLSv1_2_method(void)) /* DTLSv1.2 */
DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *DTLSv1_2_server_method(void)) /* DTLSv1.2 */
DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *DTLSv1_2_client_method(void)) /* DTLSv1.2 */
#endif


__owur const SSL_METHOD *DTLS_method(void); /* DTLS 1.0 and 1.2 */
__owur const SSL_METHOD *DTLS_server_method(void); /* DTLS 1.0 and 1.2 */
__owur const SSL_METHOD *DTLS_client_method(void); /* DTLS 1.0 and 1.2 */


#ifndef OPENSSL_NO_GMTLS
__owur const SSL_METHOD *GMTLS_method(void); /* GMTLSv1.1 */
__owur const SSL_METHOD *GMTLS_server_method(void); /* GMTLSv1.1 */
__owur const SSL_METHOD *GMTLS_client_method(void); /* GMTLSv1.1 */
#endif
会话协议的版本

    SSL_CTX *ssl_ctx = SSL_CTX_new(ssl_method);   申请会话环境

    SSL_CTX_set_cipher_list(ssl_ctx, "DEFAULT");    此函数非必要. 设置ctx使用的算法优先权 , "DEFAULT"优先使用默认算法

转自 : https://blog.csdn.net/turui/article/details/2048480
EDH-RSA-DES-CBC3-SHA
EDH-DSS-DES-CBC3-SHA
DES-CBC3-SHA
DHE-DSS-RC4-SHA
IDEA-CBC-SHA
RC4-SHA
RC4-MD5
EXP1024-DHE-DSS-RC4-SHA
EXP1024-RC4-SHA
EXP1024-DHE-DSS-DES-CBC-SHA
EXP1024-DES-CBC-SHA
EXP1024-RC2-CBC-MD5
EXP1024-RC4-MD5
EDH-RSA-DES-CBC-SHA
EDH-DSS-DES-CBC-SHA
DES-CBC-SHA
EXP-EDH-RSA-DES-CBC-SHA
EXP-EDH-DSS-DES-CBC-SHA
EXP-DES-CBC-SHA
EXP-RC2-CBC-MD5
EXP-RC4-MD5
这些算法按一定优先级排列,如果不作任何指定,将选用DES-CBC3-SHA.用SSL_CTX_set_cipher_list可以指定自己希望用的算法(实际上只是 提高其优先级,是否能使用还要看对方是否支持).
可用算法

    SSL_CTX_set_ecdh_auto(ssl_ctx, 1);   启用ECDH , openssl1.0.2以上才支持该函数

  2.载入私钥和证书, 私钥保存在本地需要密码的保护

    设置私钥密码  http://blog.chinaunix.net/uid-686647-id-1745796.html

    设置读取私钥时需要的密码(口令), 如果不设置在载入证书时会被提示需要输入密码(口令)

      void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx, pem_password_cb *cb);
      void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *ctx, void *u);
      int pem_passwd_cb(char *buf, int size, int rwflag, void *userdata);  回调函数

    设置读取私钥的密码有两种方式

      1.SSL_CTX_set_default_passwd_cb_userdata(ctx,(void*)"123456"); 直接设置密码为123456

      2.SSL_CTX_set_default_passwd_cb(ctx, pem_password_cb); 在使用私钥时调用回调函数由回调函数获得密码

      回调函数的定义, 以上面的格式定义一个回调函数,在函数体里通过snprintf(buf,size,"%s","path")等输出函数把密码及其路径输出到buf里

转自: https://www.openssl.org/docs/man1.0.2/man3/SSL_CTX_use_certificate_chain_file.html

 #include <openssl/ssl.h>

 int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x);
 int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, unsigned char *d);
 int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type);
 int SSL_use_certificate(SSL *ssl, X509 *x);
 int SSL_use_certificate_ASN1(SSL *ssl, unsigned char *d, int len);
 int SSL_use_certificate_file(SSL *ssl, const char *file, int type);

 int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file);

 int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey);
 int SSL_CTX_use_PrivateKey_ASN1(int pk, SSL_CTX *ctx, unsigned char *d,
                                 long len);
 int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type);
 int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa);
 int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, unsigned char *d, long len);
 int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type);
 int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey);
 int SSL_use_PrivateKey_ASN1(int pk,SSL *ssl, unsigned char *d, long len);
 int SSL_use_PrivateKey_file(SSL *ssl, const char *file, int type);
 int SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa);
 int SSL_use_RSAPrivateKey_ASN1(SSL *ssl, unsigned char *d, long len);
 int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type);

 int SSL_CTX_check_private_key(const SSL_CTX *ctx);
 int SSL_check_private_key(const SSL *ssl);
View Code

    载入证书和私钥及其保护密码  https://www.cnblogs.com/qiumingcheng/p/12299167.html

    int SSL_CTX_use_PrivateKey_file(SSL *ssl, const char *file, int type /*=SSL_FILETYPE_PEM*/); 载入.pem格式的私钥文件

    int SSL_CTX_use_certificate_file(SSL *ssl, const char *file, int type /*=SSL_FILETYPE_PEM*/)  载入.pem的证书文件 , 

    证书文件通常都进行了加密保护。普及一下,证书文件里肯定是有公钥的,一般没私钥,某些情况会把私钥也包含进去,但那样作太不安全了,原则上私钥是永远不会给别人看到的,就算是进行了加密保护

    int SSL_CTX_check_private_key(SSL_CTX *ctx)  检查所载入的公钥和私钥是否匹配, 匹配返回1 否则请检查错误堆栈来找出原因。

     int SSL_CTX_use_certificate_chain_file(SSL_CTX* ctx ,const char* file)  将证书链从文件加载到ctx中  用作客户端验证
 
  3.SSL socket
    SSL* ssl_session = SSL_new(SSL_CTX* ctx);     基于ctx创建一个SSL socket   在创建好一个TCP连接后
    int SSL_set_fd(SSL* ssl , int fd);         基于accept()返回的客户端套接字 和 SSL的套接字进行绑定
    int SSL_write(SSL* ssl, const void* buf, int num);  对创建好的SSL socket 进行写
       int SSL_write(SSL* ssl, const void* buf, int num);  对创建好的SSL socket 进行读
   以上就是SSL socket的通信
    
 
 
 
原文地址:https://www.cnblogs.com/yxnrh/p/13153134.html