zoukankan      html  css  js  c++  java
  • 数字证书的原理与应用&爬坑

    前言:

    说到https应该已经很熟悉了,他与http有何区别呢? 答:https更安全,因为使用了tls协议,即有证书认证的操作,具体是一种怎样的交互呢,让我们细细道来。

    0,数字证书以及网络传输加密

         假设,有两个人,一个叫 小起,一个叫 小终,小起想给小终发送数据,可是怕别人截取,篡改等等一些不安全的行为,于是经历了如下的演变过程,直到最后得到了最完美的加密过程。

     stage1: 对称加密

              小起     ----------将数据加密,并带着能解密的钥匙,一起交给小终   -----------> 小终

              问题:传输的过程中,钥匙可能被盗

     stage2:非对称加密

              小终:自己有一个秘钥对,公钥:对外公开;    私钥:自己保留;    由公钥加密的数据只能由私钥解密,由私钥加密的内容只能由公钥解密

              小起     ----------将数据用小终的公钥加密,交给小终   -----------> 小终(用小终自己的私钥解密)

              问题:传输的过程中,有人将数据截获,搞一堆烂七八糟的内容重新用小终的公钥加密,再发给小终。

     stage2进阶:签名技术的应用

          利用hash算法不可逆的特性,将正文数据进行hash计算得到摘要,当小终收到正文后同样hash计算,如果二者相同说明数据是完整的。
       同时,小起还要告诉小终,这个摘要是我计算的,可不是别人计算的的。

               小起 -----------------1)就数据用小终的公钥加密; -------------------------------------------------------------------> 小终(用自己的公钥解密数据,用小起的公钥解密签名)
                                            2)将数据用hash算法计算出摘要,并用小起的私钥对摘要进行加密(签名)

              问题:有人冒充是小起给小终发数据

     stage3:数字证书                  

              前面说了公钥/私钥都是自己家搞出来的东西,就算是被仿造了也不知道,于是将公钥"贴在第三方出具的正式文件上"(我们所说的签发数字证书)。这样就显得有保障,因为这个正式文件上可是有第三方盖章的。但同样还要能够识别这个"章"是真正权威机构的。具体原理是:

              小起,小终    <-----------从ca那里获取两样:根证书(“印章”图样),公钥(数字证书)私钥对---------CA中心(证书颁发机构)

              小起 (用根证书校验小终的数字证书)   <---------交换数字证书 -----------> 小终(用根证书校验小起的数字证书)

     整合:对称加密结合非对称加密

         考虑到效率问题,真正的业务数据是用对称加密算法加密的。所以综合以后,过程是这样的:
         通过stage3,我们现在互相已经有了对方准确的公钥,然后通过stage2的数据交换协商出对称加密秘钥自己保存好,再用stage1的对称加密算法(此时不需要携带解密秘钥)加密数据

              小起   --------- 用对称加密算法加密的数据-----------> 小终

     1,tls的握手前的准备 

           所谓的握手,其实就是我们在上一节讲述的“对称加密秘钥”的协商过程,所以再协商之前双方要先去向CA机构发请求,获得数字证书和根证书,而这个CA机构可以是自己,只要在集群范围内大家认可就可以了,所以我们通过cfssl工具生成证书,当然也可以用openssl工具。

          以下列出了步骤,有些细节可以参考这里:https://blog.csdn.net/xxb249/article/details/79449434

    1)安装cfssl

    curl -s -L -o /bin/cfssl https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 
    curl -s -L -o /bin/cfssljson https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64 
    curl -s -L -o /bin/cfssl-certinfo https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64 
    chmod +x /bin/cfssl*

    2)写根证书的配置文件

    #mkdir -p /etc/kubernetes/apiserver/
    #cd /etc/kubernetes/apiserver/
    
    //利用命令先生成一个缺省的样板的请求文件
    #cfssl print-defaults config > ca-config.json ----
    #cfssl print-defaults csr > ca-csr.json ----修改配置,配置请求文件.csr应该是什么样子的

      //根据自己的情况修改配置,ca-config.json中可以同时定义多个配置簇,一个配置簇对应一种类型的数字证书的各项参数
      #vi ca-config.json
      #vi ca-csr.json

    我的配置文件供参考

    [root@master test]# cat ca-config.json 
    {
        "signing": {
            "default": {
                "expiry": "43800h"
            },
            "profiles": {
                "client": {
                    "expiry": "43800h",
                    "usages": [
                        "signing",
                        "key encipherment",
                        "client auth"
                    ]
                },
                "server": {
                    "expiry": "43800h",
                    "usages": [
                        "signing",
                        "key encipherment",
                        "server auth",
                        "client auth"
                    ]
                }
            }
        }
    }
    View Code

    3)生成根正书

    # cfssl gencert -initca ca-csr.json | cfssljson -bare ca -
    2019/05/22 10:46:34 [INFO] generating a new CA key and certificate from CSR
    2019/05/22 10:46:34 [INFO] generate received request
    2019/05/22 10:46:34 [INFO] received CSR
    2019/05/22 10:46:34 [INFO] generating key: rsa-2048
    2019/05/22 10:46:35 [INFO] encoded CSR
    2019/05/22 10:46:35 [INFO] signed certificate with serial number 357142409311435315855410100215094728480952302820
    
    [root@master apiserver]# ll
    total 24
    -rw-r--r-- 1 root root 833 May 22 10:39 ca-config.json
    -rw-r--r-- 1 root root 997 May 22 10:46 ca.csr        ---根证书请求文件
    -rw-r--r-- 1 root root 262 May 22 10:42 ca-csr.json
    -rw------- 1 root root 1679 May 22 10:46 ca-key.pem   ---根证书对应的私钥
    -rw-r--r-- 1 root root 1350 May 22 10:46 ca.pem       ----根证书

    4)签发数字证书,首先写好配置,然后签发

    #cfssl print-defaults csr > server-csr.json
    # vi server-csr.json ---按情况修改

    //-profile参数对应ca-config.json中的一个配置簇
    # cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=server server-csr.json | cfssljson -bare server
    2019/05/30 19:37:53 [INFO] generate received request
    2019/05/30 19:37:53 [INFO] received CSR
    2019/05/30 19:37:53 [INFO] generating key: rsa-2048
    2019/05/30 19:37:53 [INFO] encoded CSR
    2019/05/30 19:37:53 [INFO] signed certificate with serial number 605959301321047408407639792005193883834034252126
    2019/05/30 19:37:53 [WARNING] This certificate lacks a "hosts" field. This makes it unsuitable for
    websites. For more information see the Baseline Requirements for the Issuance and Management
    of Publicly-Trusted Certificates, v.1.1.6, from the CA/Browser Forum (https://cabforum.org);
    specifically, section 10.2.3 ("Information Requirements").

    说明:在部署集群的时候会用到各种证书,有的文档会告诉你有server类型,peer类型,client类型......这对我来说反倒让我一脸懵逼,实际上CA机构才不管你什么类型的证书呢,我只管生成,至于你是用作服务端还是客户端还是什么的,那是你自己去配置,只不过一般情况下我们会根据使用场景生成的证书,会命名成服务端证书和客户端证书之类的。

    接下来我们来看看这些证书在tls握手中怎么被使用的。

     注:CA是个机构,该机构才能签发证书,根证书可以看做是CA的身份证明,但是我们在接下来的叙述中为了方便,就说成是根证书签发数字证书。

     2,tls的握手

    关于tlls握手的原理强烈推荐这个博客:https://baijiahao.baidu.com/s?id=1616211978225668389&wfr=spider&for=pc

    简述之:

    1,客-->服:客户端打招呼,我要访问https:服务器   

    2,服-->客:服务器把自己的数字证书(公钥)发给客户端

                         [如果使能了客户端认证]服务器端还会向客户端发请求,告知想要客户的证书

          《《《此时客户端拿到了服务端的公钥,如果使能了"跳过证书认证"则就这么着了,否则还要用根证书对该证书进行校验》》》

       证书校验的内容包括:

    • [证书链] 的可信性 trusted certificate path,方法如前文所述;

    • 证书是否吊销 revocation,有两类方式离线 CRL 与在线 OCSP,不同的客户端行为会不同;

    • 有效期 expiry date,证书是否在有效时间范围;

    • 域名 domain,核查证书域名是否与当前的访问域名匹配,匹配规则后续分析;

    3,客-->服[如果服务端有请求证书]:客户端同样把自己的数字证书(公钥)发给服务器端

          《《《此时服务端拿到了客户端的公钥,然后用根证书对该证书进行校验》》》

    小结:在这里面涉及到的证书及关系为:服务器端的数字证书(对)以及签发该证书的根证书;客户端的数字证书(对)以及签发该证书的根证书;

              所以当一个app作为服务器的时候,它必须要准备好自己的证书(对)和 客户端使用的根证书

                     当客户端访问的时候,客户端也必须要准备自己的证书(对) 和 服务器端使用的根证书

              好了,讲解到这里,我们去研究下kube-apiserver中是怎么配置这些的,就变得很容易了。

    ========================爬坑==================================

    爬坑1:使用curl命令式访问https时,证书出错

    问题描述:

    $ curl -k -v "https://myurl.com/" --cert ./client.pem --key ./client-key.pem
    
    * About to connect() to xx.xx.xx.xx port 2379 (#0)
    *   Trying xx.xx.xx.xx... connected
    * Connected to xx.xx.xx.xx (xx.xx.xx.xx) port 2379 (#0)
    * Initializing NSS with certpath: sql:/etc/pki/nssdb
    * warning: ignoring value of ssl.verifyhost
    * Unable to load client key -8178 (SEC_ERROR_BAD_KEY)
    * NSS error -8178 (SEC_ERROR_BAD_KEY)
    * Peer's public key is invalid
    * Closing connection #0
    curl: (58) Unable to load client key -8178.

    问题原因:

    首先,证书是经过的openssl ec格式加密的(或者PKCS#8?不确定,没遇到过),即以

      -----BEGIN ENCRYPTED PRIVATE KEY或BEGIN PRIVATE KEYBEGIN EC PRIVATE KEY-----为头部

    然后,在CentOS 6.8的系统里面的curl支持的https是nss版本的,而不是openssl。

       nss加密往往是给java程序使用的,一般的java程序都会加载   库文件

    所以,对于这样的证书,curl + openssl will works, but curl + nss + libnsspem.so wouldn't.

       但是对于rsa加密的证书,即-----BEGIN RSA PRIVATE KEY----- 为头的证书

                则both curl + openssl and curl + nss + libnsspem.so will work.

    最终,想要成功访问有两种方案,

       方案一:修改私钥格式为rsa,参见https://stackoverflow.com/questions/20969241/curl-58-unable-to-load-client-key-8178(未成功)

       方案二: 修改curl,让其变成curl + openssl(成功)

    解决: 重新安装curl,让其支持

    参考链接:https://www.cnblogs.com/cyleon/p/10038229.html

    核心步骤:

    # wget https://curl.haxx.se/download/curl-7.35.0.tar.gz
    # tar xf curl-7.35.0.tar.gz 
    # cd curl-7.35.0
    # ./configure --without-nss --with-ssl && make &&make install
    # echo "/usr/local/lib" >>/etc/ld.so.conf
    # ldconfig
    # curl -V
  • 相关阅读:
    hdu 4707 Pet
    hdu 3584 Cube (三维树状数组)
    poj 2155 Matrix (树状数组)
    poj 1195 Mobile phones (树状数组)
    工厂方法模式
    简单工厂模式
    关于设计模式
    UML类图
    UML
    【转载】UML用例图
  • 原文地址:https://www.cnblogs.com/shuiguizi/p/13809942.html
Copyright © 2011-2022 走看看