Https原理及实践

来源:互联网 发布:社保政府补贴数据 编辑:程序博客网 时间:2024/06/07 14:50

1.Https原理

HTTPS要使客户端与服务器端的通信过程得到安全保证,必须使用的对称加密算法,但是协商对称加密算法的过程,需要使用非对称加密算法来保证安全,然而直接使用非对称加密的过程本身也不安全,会有中间人篡改公钥的可能性,所以客户端与服务器不直接使用公钥,而是使用数字证书签发机构颁发的证书来保证非对称加密过程本身的安全。这样通过这些机制协商出一个对称加密算法,就此双方使用该算法进行加密解密。从而解决了客户端与服务器端之间的通信安全问题。


这句话本身已经总结了https的过程,在这里有几个专业的词汇可以先普及下。

  • 公钥密码体制:
    公钥密码体制分为三个部分,公钥、私钥、加密解密算法,它的加密解密过程如下:

    • 加密:通过加密算法和公钥对内容(或者说明文)进行加密,得到密文。加密过程需要用到公钥。
    • 解密:通过解密算法和私钥对密文进行解密,得到明文。解密过程需要用到解密算法和私钥。注意,由公钥加密的内容,只能由私钥进行解密,也就是说,由公钥加密的内容,如果不知道私钥,是无法解密的。

    公钥密码体制的公钥和算法都是公开的(这是为什么叫公钥密码体制的原因),私钥是保密的。大家都以使用公钥进行加密,但是只有私钥的持有者才能解密。在实际的使用中,有需要的人会生成一对公钥和私钥,把公钥发布出去给别人使用,自己保留私钥。

    RSA密码体制是一种公钥密码体制,公钥公开,私钥保密,它的加密解密算法是公开的。 由公钥加密的内容可以并且只能由私钥进行解密,并且由私钥加密的内容可以并且只能由公钥进行解密。也就是说,RSA的这一对公钥、私钥都可以用来加密和解密,并且一方加密的内容可以由并且只能由对方进行解密。

  • 对称加密算法:
    在对称加密算法中,加密使用的密钥和解密使用的密钥是相同的。也就是说,加密和解密都是使用的同一个密钥。因此对称加密算法要保证安全性的话,密钥要做好保密,只能让使用的人知道,不能对外公开。这个和上面的公钥密码体制有所不同,公钥密码体制中加密是用公钥,解密使用私钥,而对称加密算法中,加密和解密都是使用同一个密钥,不区分公钥和私钥。
    // 密钥,一般就是一个字符串或数字,在加密或者解密时传递给加密/解密算法。前面在公钥密码体制中说到的公钥、私钥就是密钥,公钥是加密使用的密钥,私钥是解密使用的密钥。

  • 非对称加密算法:
    在非对称加密算法中,加密使用的密钥和解密使用的密钥是不相同的。前面所说的公钥密码体制就是一种非对称加密算法,他的公钥和是私钥是不能相同的,也就是说加密使用的密钥和解密使用的密钥不同,因此它是一个非对称加密算法。

  • 签名和加密:
    加密,是指对某个内容加密,加密后的内容还可以通过解密进行还原。 比如我们把一封邮件进行加密,加密后的内容在网络上进行传输,接收者在收到后,通过解密可以还原邮件的真实内容。
    这里主要解释一下签名,签名就是在信息的后面再加上一段内容,可以证明信息没有被修改过,怎么样可以达到这个效果呢?一般是对信息做一个hash计算得到一个hash值,注意,这个过程是不可逆的,也就是说无法通过hash值得出原来的信息内容。在把信息发送出去时,把这个hash值加密后做为一个签名和信息一起发出去。 接收方在收到信息后,会重新计算信息的hash值,并和信息所附带的hash值(解密后)进行对比,如果一致,就说明信息的内容没有被修改过,因为这里hash计算可以保证不同的内容一定会得到不同的hash值,所以只要内容一被修改,根据信息内容计算的hash值就会变化。当然,不怀好意的人也可以修改信息内容的同时也修改hash值,从而让它们可以相匹配,为了防止这种情况,hash值一般都会加密后(也就是签名)再和信息一起发送,以保证这个hash值不被修改。至于如何让别人可以解密这个签名,这个过程涉及到数字证书等概念,我们后面在说到数字证书时再详细说明,这里您先只需先理解签名的这个概念。

以上就是一些专业词汇,在一开始也许有些抽象,但是本文在后面会结合起来具体找出这些专业词汇的引用处。

本文第一句话就对Https,进行了总结,下文就https整个原理过程进行逆向推导。

(1)最终目的:客户端与服务器端协商出一套对称密钥,用于此次客户端与服务器的通信加密。

(2)为了确保协商出一套对称密钥这个过程是安全的(即对称加密密钥不会外泄),因此采取非对称加密的方式进行协商,非对称加密方式在此处就表现在服务器将自己的公钥发送给客户端,自己保存私钥。但是如何能确保发送给客户端的公钥在发送过程中不被掉包呢?

(3)在采取非对称加密方式协商过程中,为了确保服务器确实是真正的服务器而不是冒名顶替的并且确保服务器的公钥不被第三方的人替换,因此采用了数字证书的方法,公钥就被藏在数字证书中发给客户端。

(4)为了确保数字证书不被第三方篡改,因此引入了权威的第三方认证机构——CA(Certificate Authority)认证机构用于对数字证书进行签名,以此来标识此数字证书确是由真正的服务器发送过来的,并且未经过篡改。

(5)为了确保第三方认证机构不弄虚作假……这个就没必要了,不然接下去就是个死循环。

以上几个步骤其实就涵盖了https的相关原理,以最终目的结论,进行反推导(第五步可以忽略)。

https说明图

上图概要介绍了下https的整体流程,从上文的5个步骤的反推导过程中,可以发现最初的安全根源其实就是数字证书,从这一步开始,即图中的返回证书,本文的核心其实也是集中在返回证书的这部分,即针对证书的原理及如何制作证书进行了详细描述,至于具体的协商过程在此带过,不作深究,有感兴趣的读者可自行查阅。

因此https最初的根源,或者说最关键的一环就是:确保客户端拿到的公钥就是真实服务器发送的公钥,不是假冒服务器发送的公钥,并且在发送过程中没有被篡改或者替换

2.证书的来龙去脉

2.1 证书的流程

https证书详述

2.1.1 证书预置和申请

  1. 客户端浏览器会预置根证书, 里面包含CA公钥。
  2. 服务器去CA申请一个证书。
  3. CA用自己的签名去签一个证书,指纹信息保存在证书的数字摘要里面, 然后发送给服务器。

2.1.2一次访问流程(简化)

  1. 客户端 sayHello。
  2. 服务器返回证书。
  3. 客户端验证证书内容有效性
    3-1.验证证书的有效性(过期时间, 域名是否相同等)。
    3-2. 验证证书的有效性 (是否被串改), 通过本地根证书的CA公钥解密数字摘要,看是否匹配。
  4. 如果数字签名验证通过, 就可以使用服务器证书里面提供的公钥进行下一步通信。

2.2证书的结构

证书中的内容相对较多,此处着重介绍一些最主要的元素进行描述。

  • Issuer (证书的发布机构)
    指出是什么机构发布的这个证书,也就是指明这个证书是哪个公司创建的(只是创建证书,不是指证书的使用者),一般指的是给当前证书进行签名的CA机构。

  • Valid from , Valid to (证书的有效期)
    也就是证书的有效时间,或者说证书的使用期限。 过了有效期限,证书就会作废,不能使用了。

  • Public key (公钥)
    这个我们在前面介绍公钥密码体制时介绍过,公钥是用来对消息进行加密的,第2章的例子中经常用到的。这个数字证书的公钥是2048位的,它的值可以在图的中间的那个对话框中看得到,是很长的一串数字。

  • Subject (主题)
    这个证书是发布给谁的,或者说证书的所有者,一般是某个人或者某个公司名称、机构的名称、公司网站的网址等,其实指的是实际的证书所有者,一般为服务器域名,通过这个直接判定https访问的服务器端的名称,在制作证书的时候自己手动指定。

  • Signature algorithm (签名所使用的算法)
    就是指的这个数字证书的数字签名所使用的加密算法,这样就可以使用证书发布机构的证书里面的公钥,根据这个算法对指纹进行解密。指纹的加密结果就是数字签名。

  • Thumbprint, Thumbprint algorithm (指纹以及指纹算法)
    这个是用来保证证书的完整性的,也就是说确保证书没有被修改过。 其原理就是在发布证书时,发布者根据指纹算法(一个hash算法)计算整个证书的hash值(指纹)并和证书放在一起,使用者在打开证书时,自己也根据指纹算法计算一下证书的hash值(指纹),如果和刚开始的值对得上,就说明证书没有被修改过,因为证书的内容被修改后,根据证书的内容计算的出的hash值(指纹)是会变化的。 注意,这个指纹会使用”SecureTrust CA”这个证书机构的私钥用签名算法(Signature algorithm)加密后(上图中的数字摘要)和证书放在一起。

注意,为了保证安全,在证书的发布机构发布证书时,证书的指纹和指纹算法(其实就是上图中的数字摘要),都会加密后再和证书放到一起发布,以防有人修改指纹后伪造相应的数字证书。这里问题又来了,证书的指纹和指纹算法用什么加密呢?他们是用证书发布机构的私钥进行加密的。可以用证书发布机构的公钥对指纹和指纹算法解密,也就是说证书发布机构除了给别人发布证书外,他自己本身也有自己的证书。

证书发布机构的证书是哪里来的呢???这个证书发布机构的数字证书(一般由他自己生成)在我们的操作系统刚安装好时(例如windows xp等操作系统),这些证书发布机构的数字证书(此处更确切地说应该是公钥证书,或者说是CA证书)就已经被微软(或者其它操作系统的开发机构)安装在操作系统中了,微软等公司会根据一些权威安全机构的评估选取一些信誉很好并且通过一定的安全认证的证书发布机构,把这些证书发布机构的公钥证书默认就安装在操作系统里面了,并且设置为操作系统信任的数字证书。这些证书发布机构自己持有与他自己的数字证书对应的私钥,他会用这个私钥加密所有他发布的证书的指纹作为数字签名。

2.3 证书信任链

关于证书信任链,先看看一下几个专业词汇。

  • 什么是证书?
    “证书”洋文也叫“digital certificate”或“public key certificate”。
    它是用来证明某某东西确实是某某东西的东西(是不是像绕口令?)。通俗地说,证书就好比一个公司的公章。通过公章,可以证明该介绍信确实是对应的公司发出的。理论上,人人都可以找个证书工具,自己做一个证书。那如何防止坏人自己制作证书出来骗人捏?请看后续 CA 的介绍。

  • 什么是CA?
    CA是Certificate Authority的缩写,也叫“证书授权中心”。它是负责管理和签发证书的第三方机构,就好比例子里面的中介——C 公司。一般来说,CA必须是所有行业和所有公众都信任的、认可的。因此它必须具有足够的权威性。就好比A、B两公司都必须信任C公司,才会找 C 公司作为公章的中介。

  • 什么是CA证书?
    CA 证书,顾名思义,就是CA颁发的证书。前面已经说了,人人都可以找工具制作证书。但是你一个小破孩制作出来的证书是没啥用处的。因为你不是权威的CA机关,你自己搞的证书不具有权威性。

  • 什么是证书信任链?
    实际上,证书之间的信任关系,是可以嵌套的。比如,C 信任 A1,A1 信任 A2,A2 信任 A3……这个叫做证书的信任链。只要你信任链上的头一个证书,那后续的证书,都是可以信任滴。

  • 什么是根证书?
    “根证书”的洋文叫“root certificate”,专业的解释看“这里”。为了说清楚根证书是咋回事,再来看个稍微复杂点的例子。假设 C 证书信任 A 和 B;然后 A 信任 A1 和 A2;B 信任 B1 和 B2。则它们之间,构成如下的一个树形关系(一个倒立的树)。处于最顶上的树根位置的那个证书,就是“根证书”。除了根证书,其它证书都要依靠上一级的证书,来证明自己。那谁来证明“根证书”可靠捏?实际上,根证书自己证明自己是可靠滴(或者换句话说,根证书是不需要被证明滴)。
    聪明的同学此刻应该意识到了:根证书是整个证书体系安全的根本。所以,如果某个证书体系中,根证书出了问题(不再可信了),那么所有被根证书所信任的其它证书,也就不再可信了。这个后果是相当相当滴严重(简直可以说是灾难性的)。

针对以上进行总结,所谓的证书信任,假设A信任B,B信任C,C信任D,在实际中所有经过B签名的其它证书及它们信任的子证书,那么A都会信任。即A客户端的truststore(java应用中特有的需要配置)中配置了B证书,那么访问一个(URL)服务器,服务器返回的证书只要经过B或者B信任的下级C或D签名过的证书,那么A都视为此次访问是安全的。显而易见,https此处的信任,其实就是经过签名的。

一般在一些java应用中,开启https过程中,其中有个truststore需要配置,那个如果将这个truststore配置成根证书,那么所有经过根证书签名的其它证书都是被该应用所信任的。此外,可以发现其实CA证书就是根证书中的一种,是经过权威机构发布的一类根证书而已。自己也可以制作根证书,只要把根证书导入到各个应用中的truststore中,那么所有经过根证书签名的证书都是被信任的

3.制作Https证书及相关命令总结

在数字证书使用过程中,会遇到签发证书问题,一般来说,有3个解决方法:
1.交由受信任的第三方证书颁发机构签名;
2.自签名;
3.自制CA证书并用其签名。

证书的制作方式最常见的有两种,openssl和keytool方式。openssl是类unix系统一般会自带的,主要是用在C语言当中的一种ssl方式。OpenSSL和Java KeyStore本质上没有关系,只是客户端用到Java,Java里面SSL认证加密的密码和证书需要存储到KeyStore这个容器里面,所以OpenSSL产生的相关资料需要导入keyStore容器。当然也可以反过来,用Java的KeyTool产生资料,再导出密码、证书,给服务器端C使用。不过OpenSSL比Java的keytool强大很多,openssl可以制作证书并对其它证书进行签名,但是keytool只能生成自签名证书,不可以对其它证书进行签名,换句话说,keytool没有制作根证书的能力。

3.1 openssl方式制作证书

1.生成CA证书--2种方式(1)openssl req -new -x509 -keyout ca.key -out ca.crt   //一步制作CA私钥和CA证书2)openssl genrsa -out /etc/security/hadoopStore/clusterCA.key 2048;  //生成CA私钥    openssl req -x509 -new -key /etc/security/hadoopStore/clusterCA.key -days 360 -out /etc/security/hadoopStore/clusterCA.pem;   //生成CA证书2.生成自签名证书(ambari制作证书方式)(1)openssl genrsa -out $wserver.key 2048    openssl req -new -key $wserver.key -out $wserver.csr   //生成签名请求,CSR就是Certificate Secure Request证书请求文件,一般需要签名首先制作这个文件,然后将其交给CA机构,进行认证签名后,再把证书返还给你。    openssl x509 -req -days 365 -in $wserver.csr -signkey $wserver.key -out $wserver.crt  //生成自签名证书

其实CA证书就是一个自签名证书,自签名证书用作根证书对其它证书进行签名就等同于CA证书的效用。不过利用keytool方式的根证书是无法等同于CA证书的,因为keytool生成的证书或者说自签名证书是无法对其它证书进行签名的。

1)证书查看方式:openssl x509 -noout -text -in clusterCA.pem(2)key的查看方式:openssl rsa -inform PEM   -noout -text -in  clusterCA.key (3)查看签名请求信息:openssl req -noout -text -in server.csr  (4)从一个私钥里面提取出公钥:openssl rsa -in key.pem -pubout -out pubkey.pem(5)查看一个公钥的信息:openssl rsa -noout -text -pubin -in apache.pub(6)将openssl产生的证书转换成jks的证书 :keytool -importcert -alias CA -file ca.crt -keystore ca.jks  //ambari中制作clustertruststore证书就是如此制作的。

3.2 keytool方式制作证书

1.生成自签名证书:keytool -genkeypair -alias hccluster -keyalg RSA -keysize 1024 -dname "CN=$hostname,OU=cmss,O=cmss,L=sz,ST=js,C=cn" -keypass bigdata -keystore /etc/security/hadoopStore/keystore.jks -storepass bigdata -validity 360\//此方法就是生成一个自签名证书了,其中CN即实际的服务器名称,以及其它相关信息已经在其中指定了,如果不指定,会在交互过程中手动输入,密钥库密码-storepass以及私钥密码-keypass都已经指定为bigdata2.生成证书签名请求:keytool -keystore /etc/security/hadoopStore/keystore.jks -alias hccluster -certreq -file /etc/security/hadoopStore/host.csr -storepass bigdata -keypass bigdata3.利用CA证书或者根证书执行签名:openssl x509 -req -CA /etc/security/hadoopStore/clusterCA.crt -CAkey /etc/security/hadoopStore/clusterCA.key -in /etc/security/hadoopStore/host.csr -out /etc/security/hadoopStore/host.cert -days 360 -CAcreateserial4.将签名后的证书导回密钥库:keytool -keystore /etc/security/hadoopStore/keystore.jks -storepass bigdata -alias hccluster -import -file /etc/security/hadoopStore/host.cert -keypass bigdata5.查看密钥库内容:keytool -list -v -keystore keystore.jks6.导出证书(就是访问服务端,返回的公钥证书) keytool -export -alias {别名} -keystore keystore.jks -file dd.cert7.查看证书签名请求文件 keytool -printcertreq -file host.csr8.查看证书文件 keytool -printcert -file host.cert9.修改keystore别名 keytool -changealias -keystore /etc/security/hadoopStore/keystore.jks -alias wj1-hc -destalias gg6-hc   

4. Https实践

5. 参考文献

【1】https://www.zhihu.com/question/52493697
【2】http://www.cnblogs.com/zhangshitong/p/6478721.html
【3】http://www.cnblogs.com/liyulong1982/p/6106129.html
【4】http://blog.csdn.net/u013424496/article/details/51161370

原创粉丝点击