本文共 11988 字,大约阅读时间需要 39 分钟。
什么是TLS/SSL:
数据安全的三个要素:
数据的完整性
数据的机密性
身份验证
以上三点任意一点不能满足,则数据安全得不到保障
三种加密算法:
对称加密算法
非对称加密算法(公钥加密算法)
单项加密算法(hash算法)
对称加密算法:(保证数据的机密性)
加密和解密使用同一个秘钥,例如你使用123456进行加密,对方则使用123456进行解密。
优点:算法计算速度很快。
缺点:安全性完全依赖于秘钥本身。并且秘钥管理不方便,如果A对应多个用户,则需要管理多个密码
常用的对称加密算法:AES,RC4,3DES
哈希算法:(保证数据的完整性)
哈希(Hash)算法,即散列函数。它是一种单向密码体制,即它是一个从明文到密文的不可逆的映射,只有加密过程,没有解密过程。同时,哈希函数可以将任意长度的输入经过变化以后得到固定长度的输出。哈希函数的这种单向特征和输出数据长度固定的特征使得它可以生成消息或者数据。
哈希算法的特性:
1、输入相同,输出必然相同。
2、雪崩效应:输入的一点微小改变,将会影响结果的巨大改变
3、定长输出:无论原始数据大小是是多少,结果大小都是相同的
4、不可逆:无法通过特征码还原原来的数据,就像不能通过指纹还原出一个人来一样
常用的哈希算法:MD5,SHA1,SHA256
对称加密算法和哈希算法如何保证数据的安全性?
假设A在向B传送数据时,先提取数据的特征码,然后使用和B事先协商好的对称秘钥对特征码进行加密,那么就算明文数据和特征码被C截取了,C也没有对称秘钥对特征码进行解密,所以C就算篡改了明文数据,生成的新的特征码和B解密出来的特征码不一致,B就会知道数据被篡改过了。
假如A和B从来没有见过面,也没有约定过对称密码,那么A和B如何进行密码约定?
这种情况下,需要进行秘钥交换(也叫Internet Key Exchange,简称IKE),这需要特殊的互联网协议支撑,最早的秘钥交换协议是Diffie-Hellman(openvpn就用到了它)
秘钥交换算法的好处:事先不需要约定对称密码,
秘钥交换算法的坏处:无法进行身份验证。比如A将数据发给B,正好被C截取了,那么A会和C进行秘钥交换了,那么A是无法验证对方是不是B。
于是公钥加密算法诞生了
非对称加密算法:(保证数据的机密性/实现了身份验证)
也叫公钥加密算法,使用两把完全不同但又是完全匹配的一对—和。在使用非对称加密算法加密文件时,只有使用匹配的一对公钥和私钥,才能完成对明文的加密和解密过程。明文时采用公钥加密,解密密文时使用私钥才能完成,而且发信方(加密者)知道收信方的公钥,只有收信方(解密者)才是唯一知道自己私钥的人。不对称加密算法的基本原理是,如果发信方想发送只有收信方才能解读的加密信息,发信者使用收信者的公钥加密信件,收信者使用自己的私钥钥解密信件。显然,采用不对称加密算法,收发信双方在通信之前,收信方必须将自己早已随机生成的公钥送给发信方,而自己保留私钥。由于不对称算法拥有两个,因而特别适用于中的数据。广泛应用的有和美国国家标准局提出的。以不对称加密算法为基础的加密技术应用非常广泛。
常用的非对称加密算法:RSA,DSA/DSS
公钥加密算法的两种用途:
发送方用自己的私钥加密数据,可以实现身份验证(这也是通常的用法)
发送方用对方的公钥加密数据,可以保证数据的机密性(通常用来计算对称秘钥)
注意:
公钥加密算法很少用来加密数据,因为速度太慢,性能太低。公钥加密算法比对称加密算法慢3个数量级
公钥加密算法+哈希算法,如何能保证数据的完整性,又能保证身份验证?
以A和B之间进行数据通讯为例:
假如A在生成数据后,计算出数据特征码,A再用自己的私钥加密特征码,放在数据后面,发送给B。此时C截取了这段数据,并修改了数据,重新生成了特征码,并用C自己的私钥加密特征码,放在数据后面,发送给B,而B用A的公钥是无法解密C发过来的加密过的特征码的,所以B会知道数据被篡改过。如果B用A的公钥能够解密数据,然后用单项加密算法计算出特征码和A发过来的一致,这样一来就可以实现身份验证和数据的完整性。这里使用了非对称加密算法和单项加密算法。
上面这一过程实现的前提是,B事先获取到了A的公钥,那么B怎么获取A的公钥呢?
假如B要跟A建立通讯,B向A发送信息获取A的公钥,这时候C截取了这段信息,把自己的公钥发送给了B,并告诉B自己是A,这时候B是无法验证C的身份的。这种情况怎么办?
此时只能借助于第三方机构,证书颁发机构(类似于公安机关发的身份证一样)。
证书颁发的过程:
A公司将自己的公钥和其他基本信息(如公司名、地址、域名等)提交给证书颁发机构(CA),来申请证书,第三方机构拿到A公司的信息后,先去计算这些数据的特征码,并用自己的私钥加密这段特征码,放在给A公司颁发的证书信息中,这段加密后的信息叫做数字签名。这样一来,只有第三方机构的公钥能解密数字签名。
证书验证的过程:
前提条件:证书机构是被双方信任的,客户端B有证书机构自颁发的证书(证书中有证书机构的公钥信息)
证书验证的过程如下,还是以A和B通讯过程举例:
1、B向A发起请求
2、A将自己的证书发送给B(证书中有A的公钥)
3、B验证A的证书,过程如下:
B只要能够用证书颁发机构的公钥(B有发证机构的证书,证书包含了公钥)解密出A的证书上的数字签名,就可以保证证书是由自己认可的第三方机构颁发的。并且B需要去证书机构吊销证书列表中确认该证书是否被吊销。
HTTPS会话的建立:
服务器端监听在443端口上,客户端和服务器端经过tcp3次握手建立连接,然后再开始建立SSL会话,过程如下:
1、客户端的浏览器向服务端发送客户端支持的SSL/TLS协议版本号、支持的加密算法种类、随机数(如:RSA加密算法,DES对称加密算法,SHA1摘要算法)
2、服务端向客户端浏览器回传SSL/TLS 协议版本号、选择一种客户端浏览器支持的加密算法和HASH算法、随机数、服务端证书等信息;(证书里面包含了网站地址,加密公钥,以及证书的颁发机构等信息;证书中的私钥只能用于服务器端进行解密,在握手的整个过程中,都用到了证书中的公钥和浏览器发送给服务器的随机密码以及对称加密算法)
3、客户端浏览器利用服务端回传的信息验证服务端的合法性;合法性包括:证书是否过期、发行服务器证书的CA是否可靠、证书的公钥能否正确解开服务端证书的“数字签名(使用私钥加密,只有公钥能解密)”、服务端证书上的域名和服务端实际域名是否匹配;合法则继续(浏览器栏里面会显示一个小锁头),否则断开连接
------------------------------------------------- 上面3步是验证证书合法性的过程---------------------------------------------
4、客户端浏览器产生一个随机数,然后用服务端证书的公钥对随机数进行加密,生成对称密码;根据服务端指定的HASH算法(如SHA1)计算握手消息,并使用生成的“对称密码”对握手消息加密;然后把加密后的“对称密码”和加密的握手消息发送给服务端;
5、服务端使用自己的私钥解密获得随机“对称密码”,然后使用随机“对称密码”解密客户端浏览器发送的握手消息,并验证hash与浏览器发送过来的是否一样。如果一样,则表示数据完整性没有问题。
6、服务端使用随机“对称密码”加密握手信息,发送给客户端浏览器;
7、客户端浏览器使用随机“对称密码”解密握手消息,并比较服务端发送的hash是否一致;一致此时握手结束,以后的通讯都是使用这个随机“对称密码”加密;
--------------------------------------上面4步是客户端与服务器端约定对称密码的过程-------------------------------------
测试:
自建证书验证HTTPS证书加密通讯的原理
1、使用openssl建立一个CA
2、CA需要有证书,叫自签发的证书
3、服务器端生成一对密钥,然后将公钥发送给CA,
4、CA负责签署服务器端发送过来的公钥,生成证书,并对证书进行数字签名。然后将证书发给服务器端(证书中包含了公钥)
5、Server配置服务器并使用证书,并且在客户端请求的时候发送给客户端
6、客户端使用自己本地保存好的CA的证书的公钥来验证这个证书上的第三方机构的数字签名
环境:
CA Server:172.16.206.130()
WEB SERVER:172.16.206.129
已经安装httpd,mod_ssl模块,
httpd服务已启动
网站域名为 hello.beyond.com
Client:172.16.206.131 (windows 10)
实验步骤:
1、WEB Server安装mod_ssl模块
2、CA Server创建私钥
3、CA Server生成自签发证书(给客户端导入用的,否则客户端不会信任CA颁发的证书)
4、WEB Server生成密钥
5、WEB Server生成证书颁发请求
6、CA Server为WEB Server颁发证书,并将证书拷贝到WEB Server
7、WEB Server配置ssl.conf文件以使用证书
8、客户端访问
9、客户端导入CA自签发证书后,再次访问
1、WEB Server安装mod_ssl模块
1 | yum -y install mod_ssl |
2、CA创建私钥
1 2 3 4 5 6 7 8 9 10 11 | [root@localhost ~] # cd /etc/pki/ [root@localhost pki] # ls CA ca-trust java nssdb rpm-gpg rsyslog tls [root@localhost pki] # cd CA/ [root@localhost CA] # ls certs crl newcerts private [root@localhost CA] # (umask 077; openssl genrsa -out private/cakey.pem 2048) Generating RSA private key, 2048 bit long modulus .......................................+++ ...........+++ e is 65537 (0x10001) |
确保private目录权限为600
1 2 | [root@localhost CA] # ls -ld private/ drwx------. 2 root root 4096 11月 3 22:16 private/ |
3、CA Server生成自签发证书
1)、修改openssl.conf配置文件,修改证书默认的相关设置
1 | vim .. /tls/openssl .cnf |
在 [ req_distinguished_name ] 配置段下
将以下行的内容修改为如下配置(这个设置自己随意设置):
1 2 3 4 5 | countryName_default = CN // 国家 stateOrProvinceName_default = Shanghai // 省份 localityName_default = Shanghai // 城市 0.organizationName_default = Beyond // 组织 organizationalUnitName_default = OPS // 部门 |
2)、生成自签证书
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | [root@localhost CA] # openssl req -new -x509 -key private/cakey.pem -out cacert.pem -days 3650 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) [CN]: State or Province Name (full name) [Shanghai]: Locality Name (eg, city) [Shanghai]: Organization Name (eg, company) [Beyond]: Organizational Unit Name (eg, section) [OPS]: Common Name (eg, your name or your server's hostname ) []:ca.beyond.com Email Address []:admin@beyond.com |
这里的域名应该无所谓,可以随意设置(不确定)
1 | Common Name (eg, your name or your server's hostname ) []:ca.beyond.com |
3、确认/etc/pki/CA/tls/openssl.conf文件 [ CA_default ]段配置正确
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | [ CA_default ] dir = /etc/pki/CA # Where everything is kept certs = $ dir /certs # Where the issued certs are kept crl_dir = $ dir /crl # Where the issued crl are kept database = $ dir /index .txt # database index file. #unique_subject = no # Set to 'no' to allow creation of # several ctificates with same subject. new_certs_dir = $ dir /newcerts # default place for new certs. certificate = $ dir /cacert .pem # The CA certificate serial = $ dir /serial # The current serial number crlnumber = $ dir /crlnumber # the current crl number # must be commented out to leave a V1 CRL crl = $ dir /crl .pem # The current CRL private_key = $ dir /private/cakey .pem # The private key RANDFILE = $ dir /private/ .rand # private random number file x509_extensions = usr_cert # The extentions to add to the cert # Comment out the following two lines for the "traditional" # (and highly broken) format. name_opt = ca_default # Subject Name options cert_opt = ca_default # Certificate field options |
dir = /etc/pki/CA //CA的目录路径
certs = $dir/certs //生成的证书存放的目录
crl_dir = $dir/crl //吊销的证书存放目录
new_certs_dir = $dir/newcerts //新签署的证书存放的路径
serial = $dir/serial //序列号,表示证书签署到第几个了
database = $dir/index.txt //保存证书信息,如已经签署了哪些证书,每个证书的名称
默认/etc/pki/CA路径下没有serial 和index.txt文件,需要手动创建
1 2 | [root@localhost CA] # touch index.txt [root@localhost CA] # echo 01 > serial |
4、WEB服务器上生成密钥(申请证书需要用密钥加密)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | [root@localhost pki] # cd /etc/httpd/ [root@localhost httpd] # ls conf conf.d logs modules run [root@localhost httpd] # mkdir ssl [root@localhost httpd] # ls conf conf.d logs modules run ssl [root@localhost httpd] # (umask 077; openssl genrsa 1024 > http^C [root@localhost httpd] # cd ssl/ [root@localhost ssl] # (umask 077; openssl genrsa 1024 > httpd.key) Generating RSA private key, 1024 bit long modulus ........++++++ .............++++++ e is 65537 (0x10001) [root@localhost ssl] # ll 总用量 4 -rw------- 1 root root 887 10月 31 20:32 httpd.key |
5、WEB服务器上生成证书颁发请求(csr:证书签署请求)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | [root@localhost ssl] # openssl req -new -key httpd.key -out httpd.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) [XX]:CN State or Province Name (full name) []:Shanghai Locality Name (eg, city) [Default City]:Shanghai Organization Name (eg, company) [Default Company Ltd]:Beyond Organizational Unit Name (eg, section) []:OPS Common Name (eg, your name or your server's hostname ) []:hello.beyond.com Email Address []:hello@beyond.com Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: An optional company name []: |
注意:
1、在上面生成证书请求时,国家、城市这些信息必须与CA上填写的一致
2、下面的信息不能填错,证书给哪个域名用,必须填写正确
1 | Common Name (eg, your name or your server's hostname ) []:hello.beyond.com |
1 2 | [root@localhost ssl] # ls httpd.csr httpd.key |
将WEB服务器上的csr证书签署请求文件拷贝到CA服务器
1 | [root@localhost ssl] # scp httpd.csr 172.16.42.130:/tmp |
6、CA服务器上为WEB服务器签署证书
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | [root@localhost CA] # openssl ca -in /tmp/httpd.csr -out /tmp/httpd.crt -days 3650 Using configuration from /etc/pki/tls/openssl .cnf Check that the request matches the signature Signature ok Certificate Details: Serial Number: 1 (0x1) Validity Not Before: Nov 3 15:31:25 2016 GMT Not After : Nov 1 15:31:25 2026 GMT Subject: countryName = CN stateOrProvinceName = Shanghai organizationName = Beyond organizationalUnitName = OPS commonName = hello.beyond.com emailAddress = hello@beyond.com X509v3 extensions: X509v3 Basic Constraints: CA:FALSE Netscape Comment: OpenSSL Generated Certificate X509v3 Subject Key Identifier: AD:7C:28:55:E8:FA:EE:17:4A:6E:00:A5:73:C5:42:DF:6B:EF:F6:DE X509v3 Authority Key Identifier: keyid:74:0D:C7:EF:A2:E7:97:36:D0:0C:81:D9:1F:1D:8D:1E:22:59:93:02 Certificate is to be certified until Nov 1 15:31:25 2026 GMT (3650 days) Sign the certificate? [y /n ]:y 1 out of 1 certificate requests certified, commit? [y /n ]y Write out database with 1 new entries Data Base Updated |
证书颁发成功后,可以看到CA服务器上/etc/pki/CA目录下serial文件和index.txt文件更新了
1 2 3 4 5 6 7 8 9 10 11 | [root@localhost CA] # pwd /etc/pki/CA [root@localhost CA] # ls cacert.pem crl index.txt.attr newcerts serial certs index.txt index.txt.old private serial.old [root@localhost CA] # cat index.txt V261101153125Z01unknown /C =CN /ST =Shanghai /O =Beyond /OU =OPS /CN =hello.beyond.com /emailAddress =hello@beyond.com [root@localhost CA] # cat serial 02 [root@localhost CA] # ls newcerts/ 01.pem |
将CA颁发的证书拷贝到WEB服务器
1 2 3 | [root@localhost ssl] # scp 172.16.42.130:/tmp/httpd.crt ./ root@172.16.42.130's password: httpd.crt 100% 3865 3.8KB /s 00:00 |
7、WEB Server配置服务器使用证书
1 2 3 4 | [root@localhost ssl] # cd /etc/httpd/conf.d/ [root@localhost conf.d] # ls README ssl.conf welcome.conf [root@localhost conf.d] # cp ssl.conf ssl.conf.bk |
编辑/etc/httpd/conf.d/ssl.conf文件
修改证书的路径,WEB服务器私钥的路径等信息
<VirtualHost 172.16.42.129:443> //修改虚拟主机的地址
ServerName hello.beyond.com //修改服务器的域名,这里必须和证书中的域名一样
DocumentRoot "/var/www/html" //站点根目录,必须和http访问方式的目录一样
SSLEngine on //确认SSL功能开启,默认是开启的
SSLCertificateFile /etc/httpd/ssl/httpd.crt //证书路径
SSLCertificateKeyFile /etc/httpd/ssl/httpd.key //私钥的路径
检查语法
1 2 3 | httpd -t httpd: Could not reliably determine the server's fully qualified domain name, using localhost.localdomain for ServerName Syntax OK |
启动WEB服务器
1 | service httpd restart |
查看443端口是否开启
1 2 | [root@localhost conf.d] # netstat -tunlp | grep 443 tcp 0 0 :::443 :::* LISTEN 2300 /httpd |
8、windows 客户端访问http://hello.beyond.com
通过https方式访问
CA的自签发证书拷贝到客户端上,并修改文件名字为cacert.crt后导入
9、导入证书后用HTTPS方式访问
windows上生成证书的流程
1、在windows服务器上,打开IIS站点管理器,创建证书生成请求文件
2、将该文件发给第三方的证书颁发机构,机构签署证书后,会返回两个文件,一个是证书文件,一个是证书链
3、在windows服务器上导入证书,然后在导出
4、导出的证书就可以给到其他windwos服务器使用了
注意:如果不做地散步,那么第三发机构颁发的证书只能给到原先生成证书请求的那台服务器使用,因为证书请求文件中包含了私钥文件,第三步导出证书,会将原来的私钥也给导出来,这样该证书就能在其他服务器上使用了