CentOS6.5下openssl加密解密及CA自签颁发证书详解

SSLLab网站上的免费在线工具 



OpenSSL提供的算法 可用于“密钥协商” 可用于“数字签名”
DSA -- 可以
DH 可以 --
RSA 可以 可以



session ID 或 session Ticket:



如果出于某种原因,对话中断,就需要重新握手。为了避免重新握手而造成的访问效率低下,这时候引入了session ID的概念, session ID(以及session ticke)的思想很简单,就是每一次对话都有一个编号(session ID)。如果对话中断,下次重连的时候,只要客户端给出这个编号,且服务器有这个编号的记录,双方就可以重新使用已有的“对话密钥”,而不必重新生成一把。

因为我们抓包的时候,是几个小时内第一次访问 baodu.com 首页,因此,这里并没有 Session ID.(稍会儿我们会看到隔了半分钟,第二次抓包就有这个Session ID)

session ID是目前所有浏览器都支持的方法,但是它的缺点在于session ID往往只保留在一台服务器上。所以,如果客户端的请求发到另一台服务器,就无法恢复对话。session ticket就是为了解决这个问题而诞生的,目前只有Firefox和Chrome浏览器支持。

后续建立新的https会话,就可以利用 session ID 或者 session Tickets , 对称秘钥可以再次使用,从而免去了 https 公私钥交换、CA认证等等过程,极大地缩短 https 会话连接时间。




Certificate


为了安全的将公钥发给客户端,服务端会把公钥放入数字证书中并发给客户端(数字证书可以自签发,但是一般为了保证安全会有一个专门的CA机构签发),所以这个报文就是数字证书,4097 bytes就是证书的长度。

我们打开这个证书,可以看到证书的具体信息,这个具体信息通过抓包报文的方式不是太直观,可以在浏览器上直接看。(点击chrome浏览器左上方的绿色锁型按钮)




在client hello里面,客户端给出了多种加密族 Cipher,而在客户端所提供的加密族中,服务端挑选了“TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256”

(a)TLS为协议,使用ECDHE、RSA作为密钥交换算法;

(b)AES_256_CBC是对称加密算法(密钥和初始向量的长度都是256 其中256是密钥长度,CBC是分组方式);

(c)SHA是哈希的算法。

意味着服务端会使用ECDHE-RSA算法进行密钥交换,通过AES_128_GCM对称加密算法来加密数据,利用SHA256哈希算法来确保数据完整性。



深入揭秘HTTPS安全问题&连接建立全过程

https://zhuanlan.zhihu.com/p/22142170

RSA是目前唯一一个既能用于密钥交换又能用于证书签名的算法,RSA 是最经典,同时也是最常用的是非对称加解密算法。


2017-1-19

在签名算法中,私钥用于对数据进行签名,公钥用于对签名进行验证。这也可以直观地进行理解:对一个文件签名,当然要用私钥,因为我们希望只有自己才能完成签字。验证过程当然希望所有人都能够执行,大家看到签名都能通过验证证明确实是我自己签的。

数字签名无非就两个目的:
证明这消息是你发的;
证明这消息内容确实是完整的---也就是没有经过任何形式的篡改(包括替换、缺少、新增)。


2017-1-18

检验: https://www.ssllabs.com/ssltest/index.html

CA 认证分为三类:DV ( domain validation),OV ( organization validation),EV ( extended validation),证书申请难度从前往后递增,貌似 EV 这种不仅仅是有钱就可以申请的。

对于一般的小型网站尤其是博客,可以使用自签名证书来构建安全网络,所谓自签名证书,就是自己扮演 CA 机构,自己给自己的服务器颁发证书。


2017-1-17

TLS中的算法分为4类:
authentication (认证)算法
key exchange(密钥交换)算法
encryption(加密)算法
message authentication code (消息认证码 简称MAC)算法


例: facebook:www.facebook.com采用128位加密技术。

       该连接采用TLS 1.2。该连接使用AES_128_GCM(迄今为止依然很可靠,极难被破解的加密算法)进行加密和身份验证,并使用ECDHE_ECDSA(迄今为止也很可靠)作为密钥交换机制。

        twitter:twitter.com采用128位加密技术。该连接采用TLS 1.2。该连接使用AES_128_GCM进行加密和身份验证,并使用ECDHE_RSA(很可靠)作为密钥交换机制。

       google plus(所有google服务都一样): plus.google.com采用256位加密技术。该连接采用TLS 1.2。该连接使用CHACHA20_POLY1305(也是让人放心的加密算法)进行加密和身份验证,并使用ECDHE_ECDSA(迄今为止也很可靠)作为密钥交换机制。),只有本地浏览器与目标服务器知道内容,谁也没法进行数据的窃取监听。



生成密钥、证书

第一步:为服务器端和客户端准备公钥、私钥

 
     
# 生成服务器端私钥
openssl genrsa -out server.key 1024
# 生成服务器端公钥
openssl rsa -in server.key -pubout -out server.pem
# 生成客户端私钥
openssl genrsa -out client.key 1024
# 生成客户端公钥
openssl rsa -in client.key -pubout -out client.pem

第二步:生成 CA 证书

 
     
# 生成 CA 私钥
openssl genrsa -out ca.key 1024
# X.509 Certificate Signing Request (CSR) Management.
openssl req -new -key ca.key -out ca.csr
# X.509 Certificate Data Management.
openssl x509 -req -in ca.csr -signkey ca.key -out ca.crt

在执行第二步时会出现:

 
     
➜ keys openssl req -new -key ca.key -out ca.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:CN
State or Province Name (full name) [Some-State]:Zhejiang
Locality Name (eg, city) []:Hangzhou
Organization Name (eg, company) [Internet Widgits Pty Ltd]:My CA
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:localhost
Email Address []:


注意,这里的 Organization Name (eg, company) [Internet Widgits Pty Ltd]: 后面生成客户端和服务器端证书的时候也需要填写,不要写成一样的!!!可以随意写如:My CA, My Server, My Client。

然后 Common Name (e.g. server FQDN or YOUR name) []: 这一项,是最后可以访问的域名,我这里为了方便测试,写成 localhost,如果是为了给我的网站生成证书,需要写成 barretlee.com

第三步:生成服务器端证书和客户端证书

 
     
# 服务器端需要向 CA 机构申请签名证书,在申请签名证书之前依然是创建自己的 CSR 文件
openssl req -new -key server.key -out server.csr
# 向自己的 CA 机构申请证书,签名过程需要 CA 的证书和私钥参与,最终颁发一个带有 CA 签名的证书
openssl x509 -req -CA ca.crt -CAkey ca.key -CAcreateserial -in server.csr -out server.crt
# client 端
openssl req -new -key client.key -out client.csr
# client 端到 CA 签名
openssl x509 -req -CA ca.crt -CAkey ca.key -CAcreateserial -in client.csr -out client.crt

此时,我们的 keys 文件夹下已经有如下内容了:

 
     
.
├── https-client.js
├── https-server.js
└── keys
├── ca.crt
├── ca.csr
├── ca.key
├── ca.pem
├── ca.srl
├── client.crt
├── client.csr
├── client.key
├── client.pem
├── server.crt
├── server.csr
├── server.key
└── server.pem

看到上面两个 js 文件了么,我们来跑几个demo。











如上图所示,简述如下:

  • 客户端生成一个随机数 random-client,传到服务器端(Say Hello)
  • 服务器端生成一个随机数 random-server,和着公钥,一起回馈给客户端(I got it)
  • 客户端收到的东西原封不动,加上 premaster secret(通过 random-clientrandom-server 经过一定算法生成的东西),再一次送给服务器端,这次传过去的东西会使用公钥加密
  • 服务器端先使用私钥解密,拿到 premaster secret此时客户端和服务器端都拥有了三个要素:random-clientrandom-server 和 premaster secret
  • 此时安全通道已经建立,以后的交流都会校检上面的三个要素通过算法算出的 session key



发送HTTPS请求首先要进行SSL/TLS握手,握手过程大致如下:

  • 客户端发起握手请求,携带随机数、支持算法列表等参数。
  • 服务端收到请求,选择合适的算法,下发公钥证书和随机数。
  • 客户端对服务端证书进行校验,并发送随机数信息,该信息使用公钥加密。
  • 服务端通过私钥获取随机数信息。
  • 双方根据以上交互的信息生成session ticket,用作该连接后续数据传输的加密密钥。

上述过程中,第3步中客户端需要验证服务端下发的证书,验证过程有以下两个要点:

  • 客户端用本地保存的根证书解开证书链,确认服务端下发的证书是由可信任的机构颁发的。
  • 客户端需要检查证书的domain域和扩展域,看是否包含本次请求的host。

如果上述两点都校验通过,就证明当前的服务端是可信任的,否则就是不可信任,应当中断当前连接。







(1)自签名证书(一般用于顶级证书、根证书): 证书的名称和认证机构的名称相同.
(2)根证书:根证书是CA认证中心给自己颁发的证书,是信任链的起始点。任何安装CA根证书的服务器都意味着对这个CA认证中心是信任的。
    数字证书 是由证书认证机构(CA)对证书申请者真实身份验证之后,用CA的根证书对申请人的一些基本信息以及申请人的公钥进行签名(相当于加盖发证书机构的公章)后形成的一个数字文件。

    数字证书 包含证书中所标识的实体的公钥(就是说你的证书里有你的公钥),由于证书将公钥与特定的个人匹配,并且该证书的真实性由颁发机构保证(就是说可以让大家相信你的证书是真的)

    因此,数字证书为如何找到用户的公钥并知道它是否有效这一问题提供了解决方案。


openssl中有如下后缀名的文件

.key格式:私有的密钥

.csr格式:证书签名请求(证书请求文件),含有公钥信息,certificate signing request的缩写

.crt格式:证书文件,certificate的缩写

.crl格式:证书吊销列表,Certificate Revocation List的缩写

.pem格式:用于导出,导入证书时候的证书的格式,有证书开头,结尾的格式



正文

   openssl是一个开源程序的套件、这个套件有三个部分组成、一是libcryto、这是一个具有通用功能的加密库、里面实现了众多的加密库、二是libssl、这个是实现ssl机制的、他是用于实现TLS/SSL的功能、三是openssl、是个多功能命令行工具、他可以实现加密解密、甚至还可以当CA来用、可以让你创建证书、吊销证书、这里我们用opensslenc对一个文件进行加密看看:
   # openssl enc -des3 -a -salt -in /etc/fstab -out /tmp/fstab.cipher   加密
   # cat /tmp/fstab.cipher
   # openssl enc -d -des3 -a -salt -in /tmp/fstab.cipher -out/path/to/fstab.cipher   解密


数字证书:

   证书格式通常是x509的数字证书的格式、还有pkcs等其他的。
    对于x509这种证书内容当中都包含哪些呢:
    1、公钥和也就是有效期限。
    2、持有者的个人合法身份信息、这个信息有可能是一个公司、也可能是个人、也可以是主机名。
    3、证书的使用方式、比如用来进行主机之间的认证等。
    4、CA(证书颁发机构)的信息
    5、CA的数字签名、CA的证是自签证书    

公钥加密、也叫非对称加密
   公钥加密最大的特性就是密钥成对的、公钥称为public key(pkey)、私钥称为secret key(skey)、一般而言、公钥用来加密、私钥用来解密、如果要实现电子签名那就是私钥来用加密、公钥用来解密、而公钥是可以给任何人的、私钥就得自己保存;公钥加密一般不会加来对数据加密、因为他的加密速度很慢、比对称加密慢3个数量级(一个数量级是10倍、3个就是1000倍)、所以公钥加密通常用于密钥交换(IKE)和身份认证的。
   他的常用算法有:RSA和EIGamal、目前RSA是比较广泛的加密算法、而DSA(DigitalSignature Algorithm)只能加来做签名、而无法加于加密的算法
   他的工具通常用:gpg、opensslrsautl
   


单向加密、也叫
hash算法:(One-Way加密)
   用不生成数据指纹的、也叫数据摘要算法、输出是定长的、MD5是128位定长输出、SHA1定长输出160位、他的特性是不会出现碰撞的、每位数据只要有一位不一样就会产生巨大的变化、我们称这种为雪崩效应、常用的算法MD5、SHA1、SHA512、常用工具有sha2sum、md5sum、cksum、openssldgst。
   # sha1sum fstab
   # openssl dgst -sha1 fstab



信息摘要码:
   MAC(Message Authentication Code):通常应用于实现在网络通信中保证所传输的数据完整性、他的基本方式就是基于MAC将要通信的数据使用单向加密的算法获取定长输出、而后将这定长输出安全可靠的送达到接收方的一种机制、简单来讲我们客气端发送数据给服务器时、客户端会计算这段数据的特征码、并而将这段特征码发送给服务器端、但是这种特征码不能简单的这样传送过去、他要基于MAC、调用单向加密计算这段特征码、而后将加密的结果发送给服务器端、保证特征码不会被人修改、这是单向加密的一种实现、一种延伸应用;
   他的常用算法有:CBC-MAC、HMAC    
   对于openssl来讲、如果你是客户端、他可以帮我们生成密钥对、帮我们生成证书申请、如果是发证方、他可以帮发证方自签证书、还可以签署证书、还可以生成吊销列表、当然大范围内全球内使用openCA。
    那接下来我们就用openssl完成证书生成、签署、颁发以及吊销等功能:

 

实现步骤
   首先自己得有一个证书、那就先自签一个证书、用openssl实现私有CA、CA的工作目录都是在/etc/pki/CA下、而CA的配置文件在/etc/pki/tls/openssl.cnf这个文件中。


   生成CA私钥、这里要注意、公钥是按某种格式从私钥中提取出来的、公钥和私钥是成对的、生成私钥也就有了公钥:

   # (umask 077; openssl genrsa -out private/cakey.pem 2048)   


   在当前shell中用()执行命令表示括号中的命令要在子shell中执行,2048表示密钥的长度、-out后面表示生成密钥文件保存的路径,生也的文件权限是666、而这个文件不能被别人访问、所在666-077就得到权限600:
   

   查看公钥或提取公钥、这个并不是必要步骤:
   # openssl rsa -in private/cakey.pem -pubout -text


   

   生成自签证书、用openssl中req这个命令、叫证书请求:

   # openssl req -new -x509 -key private/cakey.pem -out cacert.pem -days 3650    



   在CA的目录下创建两个文件:
   # touch index.txt serial

   OK、CA的证书有了、那接下来就是给客户签署证书了;我这里换另一台主机来做客户、向CA了起签署申请、如果要给服务器使用、那一定要跟你的服务器名保持一致、我们这里是以web服务器使用的、所以生成的私钥也要放在服务器的目录下


   我这里以httpd为例:
   生成密钥对、我们专门分建一个目录来存放:
   # mkdir /etc/httpd/ssl
   # (umask 077; openssl genrsa -out httpd.key 1024)


   

   客户端生成证书签署请求:
   # openssl req -new -key httpd.key -out httpd.csr

   再把httpd.csr发给远程主机的CA签署
   # scp httpd.csr 172.16.251.171:/tmp/

   再切换到远程主机的/tmp看一下有没有一个叫httpd.csr的文件:

   于是我们的CA检查信息完后就可以签署了:
   # openssl ca -in /tmp/httpd.csr -out /tmp/httpd.crt -days 3655

   再把签署好的证书发送回去给客户端的主机:
   # scp httpd.crt 172.16.251.127:/etc/httpd/ssl/


   发送给客户端主机了我们就可以去查看一下了:

   # ls -l /etc/httpd/ssl

   于是我们的客户端主机就可以配置使用CA签署的证书了。



   如果说证书过期了怎么吊销呢:(要在CA主机上吊销)
   # openssl ca -revoke httpd.crt


   这个证书制作好后我们就可以在
windows下安装我们制作好的证书了:

   第一步:


   第二步:


   第三步:


   第四步:


   第五步:


   第六步:





结束

   OK、以上就是我们制作证书和在windows下安装证书的过程、但在URL路径下一定是要输入https://www.tanxw.com就会看到证书的效果了、这里我这个www.tanxw.com的主机名是做实验用了、这里我就不做解析测试了、有兴趣的朋友可以关注后期的文章、在此、如果大神发现有什么不对的欢迎指出、谢谢了!







SSL双向认证原理以及期间证书的使用



要想弄明白SSL认证原理,首先要对CA有有所了解,它在SSL认证过程中有非常重要的作用。说白了,CA就是一个组织,专门为网络服务器颁发证书的,国际知名的CA机构有VeriSign、Symantec,国内的有GlobalSign。每一家CA都有自己的根证书,用来对它所签发过的服务器端证书进行验证。

如果服务器提供方想为自己的服务器申请证书,它就需要向CA机构提出申请。服务器提供方向CA提供自己的身份信息,CA判明申请者的身份后,就为它分配一个公钥,并且CA将该公钥和服务器身份绑定在一起,并为之签字,这就形成了一个服务器端证书。

如果一个用户想鉴别另一个证书的真伪,他就用 CA 的公钥对那个证书上的签字进行验证,一旦验证通过,该证书就被认为是有效的。证书实际是由证书签证机关(CA)签发的对用户的公钥的认证。

证书的内容包括:电子签证机关的信息、公钥用户信息、公钥、权威机构的签字和有效期等等。目前,证书的格式和验证方法普遍遵循X.509 国际标准。

下图使用XCA工具模拟CA来进行制作证书:ca.crt是CA的根证书,server.p12是服务器端证书,client.p12是客户端证书。


1、客户端验证服务器流程

正规的做法:

服务提供者(例如百度)向国际知名的证书颁发机构(CA)申请一本服务器证书。比如百度首页上,点击那个小锁头标志,可以看到百度是使用国际知名的证书机构VeriSign颁发的服务器证书。

客户端(浏览器)访问服务器(比如百度)时,服务器就在SSL协议握手时把服务器证书发送给用户浏览器。客户端在本地如果存储有VeriSign的CA根证书,那么用该根证书对服务器证书进行验证一定会通过的。

2、服务器验证客户端流程

服务器端通过根CA给客户端颁发客户端证书,在制作客户端证书时加上和机器相关的信息就可以保证在特定的时候某个帐号只能在这台机器上和服务器交换报文,比如我们用支付宝时必须下载安装数字证书时,可以命名这本证书叫"我的笔记本"或者是"公司电脑"之类的,就是支付宝给用户颁发证书,只能在这台机器上用,你换了机器就必须重新申请。

建立SSL连接时,先是服务器将自己的服务器证书发给客户端,验证通过后,客户端就把自己的客户端证书发给服务器进行验证,如果客户端证书和服务器证书都是通过同一家CA颁发的,那么验证一定会通过,通过后再进行后面的处理。

客户端安装CA根证书ca.crt到客户端信任证书库中,服务器端安装CA根证书ca.crt到服务器信任证书库中。

SSL握手时,服务器先将服务器证书server.p12发给客户端,客户端会到客户端信任证书库中进行验证,因为server.p12是根证书CA颁发的,所以验证通过;

然后客户端将客户端证书client.p12发给服务器,同理因为client.p12是根证书CA颁发的,所以验证通过。




猜你喜欢

转载自blog.csdn.net/andylau00j/article/details/54586438