一、HTTPS的证书

        HTTPS是HTTP+TLS结合的产物。

        HTTPS利用TLS可以完成:

                ①身份认证(防止冒充身份)

                ②加密数据(防止监听到数据)

                ③保证信息的完整性(防止信息的篡改)

        而HTTPS的证书(certification)就是完成身份认证功能,防止他人冒充你。

二、HTTPS证书的作用

服务器的身份。总不能我说是谁就是谁把。得有一个东西证明我是谁。从而HTTPS证书就出现了。 就和现实世界一样,需要一个东西证明你是谁,而我们的身份证就是证明我们是谁的工具。

身份证。身份证就是为了证明我们的身份而来的。证书就是证明我们访问的服务器是谁一样。

由于我们信任公安局,而公安局会为他们信任的每一个人发送一个身份证,来证明他们是谁。从而当我们拿着公安局发送的身份证的时候,就知道对方是谁了。因为我们信任公安局,而公安局告诉我们对方是谁,从而我们确定他是谁。

几个证书机构(CA)(相当于:公安局)。浏览器信任证书机构CA,而证书机构CA会为他们信任的服务器发送一个证书,证明服务器是谁。从而当浏览器拿到他们信任的CA签发的证书的时候,就知道访问的服务器是谁了。从而进行身份认证,看看这个服务器是不是我们要访问的服务器,防止是一个钓鱼网址。

        简单来说:证书就是用来证明你是谁的东西。

        

三、证书包含的内容

        上面说证书是为了身份的认证,就和我们的身份证是一样的。里面就会包含一些服务器的一些基本信息。一般会包含以下内容:

最重要的就是域名信息(DNS)

        ②所有者(服务器)的公钥:相当于我们的身份证号。用于加密信息使用。

        ③证书的有效期:和我们身份证一样,有一定的有效期

        ④证书的签发机构:和我们的公安局一样,用来发放身份证。

     

四、证书的认证过程

    4.1 现实世界的认证过程

         通过一个例子说明证书的认证过程:旅客入住酒店

         旅客信任公安局,酒店也信任公安局。当旅客想入住酒店时,旅客必须证明他是谁。所以旅客向公安局申请的一个身份证来证明他是谁。

        ①酒店首先会让旅客出示身份证,来看看你是谁。

        ②会核对你出示的身份证。因为不是所有身份证都是由公安局签发的,可能是假冒的身份证。该身份证不要是一个伪造的身份证。即看看身份证的签发机构是不是公安局。是不是由信任的人签发的。

        ③看看身份证是不是过期。

        ④看看身份证是否和本人一致。不要拿着他人的身份证入住酒店

        ⑤当第二步到第四步都通过的时候,酒店就知道旅客是谁了。

   4.2 互联网的认证过程

        当我们访问一个www.baidu.com的时候。如何证明我们正在访问的是百度的网址,而不是一个钓鱼的百度网站呢。

        先说明一下对应关系:

                浏览器      ====>        酒店     (浏览器让服务器出示证书)

                服务器      ====>        旅客

                CA            ====>        公安局

        首先浏览器有一份信任的证书机构CA列表,其中公安局算是一个CA。浏览器有一个信任CA列表。

受信任的CA列表中的一个CA进行证书的申请,来证明他们是谁。由这些受信任的CA签发一个证书。

        ①当访问www.baidu.com服务器的时候,浏览器首先让服务器出示一下证书,来看看你是谁。

        ②会对证书进行验证,不是所有的证书都是由信任的CA签发的。即看看证书是不是由受信任的CA列表中的任何一个签发的,如果有一个,则表示是有效的证书,如果一个也没有,则证书不是一个有效的证书。

        ③看看证书是不是在有效期内

        ④看看证书内的主题备用名称和我们访问的服务器是不是同一个地址,防止那其他服务器的证书通过验证。即对比是不是本人。

        ⑤当第二步到第四步都通过的时候,浏览器知道服务器是谁了。

   4.3 注意事项

        不要在电脑或者手机上随便的安装根证书。一个根证书可以理解为一个证书机构CA。当安装一个根证书之后,就表示我们信任这个证书机构CA。就会在受信任的CA列表中加入这个CA。那么由这个根证书签发的所有证书都将会收到信任。因为我们信任了这个根证书,相当于在我们信任关系中加入一个另一个信任的人。

        举一个例子:

        ①假设我们在PC端安装一个钓鱼网站发送的一个根证书crt。安装之后则表示我们已经信任这个根证书代表的CA。

        ②接着攻击者入侵了你们的DNS服务器,又或者修改了hosts的配置文件,将www.baidu.com改成指向他们的IP地址。因为所有的域名都会先经过DNS服务器,获取到要访问的服务器的IP地址。

        ③当浏览器访问https://www.baidu.com时,浏览器会向攻击者指定的服务器请求出示证书,服务器出示一张由第一步安装的根证书签发的证书,并返回客户端。

        ④然后客户端进行4.2小节中的第二步到第四步,来认证发送过来的证书。因为PC端安装了攻击者发送的根证书,所以在受信任的CA列表中就有了这个根证书。所以这是三个步骤将都能通过,浏览器认为你正在访问是真正的https://www.baidu.com。

        ⑤但你在伪造的https://www.baidu.com输入任何隐私信息时,都将发送到攻击者指定的服务器中。

五、利用OpenSSL安装证书

        证书是用来证明服务器的身份的,而证书是由证书机构CA签发的。

        由正规的CA签发的证书,是不需要安装的,因为浏览器内置了一些受信任的CA列表。但是需要收钱的

不收钱的。但是需要手动进行安装。不然浏览器默认不会信任自己签发的根证书。

        下面看看如何使用OpenSSL创建一个证书

        5.1 创建一个证书机构CA即根证书

证书机构CA申请一个证书,所以我们需要创建一个证书机构CA。来为服务器签发一个证书,并将创建证书机构CA安装到PC上。

                ①创建RSA秘钥:

                        openssl genrsa -out MXCA.key 2048

                ②利用RSA创建一个自签名的根证书

                        openssl req -x509 -new -key MXCA.key -days 3560 -out MXCA.pem                 

openssl 获取证书公钥 openssl 验证证书_ca证书

                 ③双击MXCA.pem,进行安装根证书,common Name就是显示的名称。倒数第二项

openssl 获取证书公钥 openssl 验证证书_ca证书_02

        

        5.2 使用CA为服务器创建浏览器需要的证书

证书申请文件CSR。证书申请文件中包含服务的基本信息,公钥等信息

                ①首先创建服务器的工私钥并创建一个证书申请文件csr

                         openssl req -newkey rsa:2048 -out server.csr -keyout server.key               

openssl 获取证书公钥 openssl 验证证书_HTTPS_03

                  ②创建服务器的扩展信息,例如域名等等信息(重要,不然浏览器会出现不安全的字样),保存为server.ext文件

basicConstraints=CA:FALSE
keyUsage=digitalSignature, keyEncipherment, dataEncipherment
extendedKeyUsage=serverAuth, clientAuth
subjectAltName=@MXDNSName
[ MXDNSName ]
DNS.1=www.baidu.com
DNS.2=*.mx.com

openssl 获取证书公钥 openssl 验证证书_openssl 获取证书公钥_04

                ③签发证书

                        openssl x509 -req -in server.csr -CA MXCA.pem -CAkey MXCA.key -CAcreateserial -days 356 -out server.crt -sha256 -extfile server.ext

openssl 获取证书公钥 openssl 验证证书_https_05

                到此证书就创建完成了。

六、附加

                在JAVA程序中需要使用p12证书,我们可以使用crt转化为p12证书,在Java程序中使用

                       openssl pkcs12 -export -in server.crt -inkey server.key -out server.p12              

openssl 获取证书公钥 openssl 验证证书_openssl 获取证书公钥_06

                 最后我们在Java程序中加入:

server.ssl.key-store=classpath:server.p12
server.ssl.key-store-password=qazw
server.ssl.keyStoreType=PKCS12

                就可以在https进行访问了,但是这时就不法使用HTTP进行请求了。如果想HTTP和HTTPs都有的话,则使用:

@Bean
    public TomcatServletWebServerFactory servletContainer() {
        TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory() {
            @Override
            protected void postProcessContext(Context context) {
                SecurityConstraint constraint = new SecurityConstraint();
                constraint.setUserConstraint("CONFIDENTIAL");
                SecurityCollection collection = new SecurityCollection();
                collection.addPattern("/*");
                constraint.addCollection(collection);
                context.addConstraint(constraint);
            }
        };
        tomcat.addAdditionalTomcatConnectors(httpConnector());
        return tomcat;
    }

//    @Bean
    public Connector httpConnector() {
        Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
        connector.setScheme("http");
        //Connector监听的http的端口号
        connector.setPort(8883);
        connector.setSecure(true);
        //监听到http的端口号后转向到的https的端口号
        connector.setRedirectPort(8882);
        return connector;
    }

如果在Nginx上进行HTTPS请求:

server {
    listen 443;
    ssl on;
    #ssl证书的pem文件路径
    ssl_certificate  /root/card/huiblog.top.pem;
    #ssl证书的key文件路径
    ssl_certificate_key /root/card/huiblog.top.key;
}