本文部分参考:
https://www.wosign.com/faq/faq2016-0309-03.htm
https://www.wosign.com/faq/faq2016-0309-04.htm
http://blog.csdn.net/hherima/article/details/52469674
什么是SSL,什么是TLS呢?官话说SSL是安全套接层(secure sockets layer),TLS是SSL的继任者,叫传输层安全(transport layer security)。说白点,就是在明文的上层和TCP层之间加上一层加密,这样就保证上层信息传输的安全。如HTTP协议是明文传输,加上SSL层之后,就有了雅称HTTPS。它存在的唯一目的就是保证上层通讯安全的一套机制。它的发展依次经历了下面几个时期,像手机软件升级一样,每次更新都添加或去除功能,比如引进新的加密算法,修改握手方式等。
SSL1.0: 已废除
SSL2.0: RFC6176,已废除
SSL3.0: RFC6101,基本废除
TLS1.0: RFC2246,目前大都采用此种方式
TLS1.1: RFC4346
TLS1.2: RFC5246,没有广泛使用
TLS1.3: IETF正在酝酿中
下面我们将介绍TLS1.x 如何保证通讯安全。
如何保证安全呢?你说安全就安全吗,究竟是怎么实现的呢?绝对安全吗?
哈,有人的地方就有江湖,有江湖的地方就没有绝对的安全。但SSL/TLS确实可以极大程度保证信息安全。下面根据图一 SSL/TLS 工作流来一览实现过程。
CA 的证书 ca.crt 和 SSL Server的证书 server.crt 是什么关系呢?
1) SSL Server 自己生成一个 私钥/公钥对。server.key/server.pub // 私钥加密,公钥解密!
2) server.pub 生成一个请求文件 server.req. 请求文件中包含有 server 的一些信息,如域名/申请者/公钥等。
3) server 将请求文件 server.req 递交给 CA,CA验明正身后,将用 ca.key和请求文件加密生成 server.crt
4) 由于 ca.key 和 ca.crt 是一对, 于是 ca.crt 可以解密 server.crt.
在实际应用中:如果 SSL Client 想要校验 SSL server.那么 SSL server 必须要将他的证书 server.crt 传给 client.然后 client 用 ca.crt 去校验 server.crt 的合法性。如果是一个钓鱼网站,那么CA是不会给他颁发合法server.crt证书的,这样client 用ca.crt去校验,就会失败。比如浏览器作为一个 client,你想访问合法的淘宝网站https://www.taobao.com, 结果不慎访问到 https://wwww.jiataobao.com ,那么浏览器将会检验到这个假淘宝钓鱼网站的非法性,提醒用户不要继续访问!这样就可以保证了client的所有https访问都是安全的。
何为SSL/TLS单向认证,双向认证?
单向认证指的是只有一个对象校验对端的证书合法性。
通常都是client来校验服务器的合法性。那么client需要一个ca.crt,服务器需要server.crt,server.key
双向认证指的是相互校验,服务器需要校验每个client,client也需要校验服务器。
server 需要 server.key 、server.crt 、ca.crt
client 需要 client.key 、client.crt 、ca.crt
客户端发起请求,以明文传输请求信息,包含版本信息,加密套件候选列表,压缩算法候选列表,随机数,扩展字段等信息,相关信息如下:
客户端计算所有接收信息的 hash 值,并采用协商密钥解密 encrypted_handshake_message,验证服务器发送的数据和密钥,验证通过则握手完成;
开始使用协商密钥与算法进行加密通信。
我们搭建的SSL/TLS服务器是192.168.111.100,client是192.168.111.101. client 需要认证 server的合法性。
我们只看 TLSv1.1 的数据包:
第一包(No. 25) Client Hello 包,即SSL/TLS单向认证流程的(1)
第二包(No. 27) Server Hello 包,包含服务器证书等。即SSL/TLS单向认证流程的(2)
第三包(No. 28) 服务器证书验证完成,同时发送client key exchange+change cipher spec + encrypted handshake message.即SSL/TLS单向认证流程的(4)
第四包(No. 29)秘钥协商,change cipher spec + encrypted hanshake message.即SSL/TLS单向认证流程的(5)
第五包(No. 30)握手完成。开始上层数据传输。SSL/TLS单向认证流程的(7)
和单向认证几乎一样,只是在client认证完服务器证书后,client会将自己的证书client.crt传给服务器。服务器验证通过后,开始秘钥协商。
实际wireshark分析:
和单向认证一样:
我们搭建的SSL/TLS服务器是192.168.111.100,client是192.168.111.101. client 需要认证 server的合法性,server也需要认证client的合法性!
我们只看 TLSv1.1 的数据包:
第一包(No. 55) Client Hello 包,即SSL/TLS单向认证流程的(1)
第二包(No. 57) Server Hello 包,包含服务器证书等。即SSL/TLS单向认证流程的(2)
第三包(No. 60) 服务器证书验证完成,同时发送客户端的证书client.crt ,同时包含client key exchange+change cipher spec + encrypted handshake message.即SSL/TLS单向认证流程的(4)
第四包(No. 61)服务器验证客户端证书的合法性。通过后进行秘钥协商,change cipher spec + encrypted hanshake message.即SSL/TLS单向认证流程的(5)
重传包(No. 62)由于网络原因,TCP重传第No. 60包。
第五包(No. 64)握手完成。开始上层数据传输。SSL/TLS单向认证流程的(7)
crt/key/req/csr/pem/der等拓展名都是什么东东?
1) .crt 表示证书, .key表示私钥, .req 表示请求文件,.csr也表示请求文件, .pem表示pem格式,.der表示der格式。
文件拓展名你可以随便命名。只是为了理解需要而命名不同的拓展名。但文件中的信息是有格式的,和exe,PE格式一样,证书有两种格式。
pem格式和der格式。所有证书,私钥等都可以是pem,也可以是der格式,取决于应用需要。
pem和der格式可以互转:
openssl x509 -in ca.crt -outform DER -out ca.der //pem -> der
openssl x509 -inform der -in ca.der -out ca.pem // der -> pem
pem格式:经过加密的文本文件,一般有下面几种开头结尾:
-----BEGIN RSA PRIVATE KEY-----
-----END RSA PRIVATE KEY-----
or:
-----BEGIN CERTIFICATE REQUEST-----
-----END CERTIFICATE REQUEST-----
or:
----BEGIN CERTIFICATE-----
-----END CERTIFICATE-----
der格式: 经过加密的二进制文件。
2) 证书中含有 申请者公钥、申请者的组织信息和个人信息、签发机构 CA的信息、有效时间、证书序列号等信息的明文,同时包含一个签名。如查看百度证书详细信息。
a) 先下载百度证书
火狐浏览器访问https://www.baidu.com/, 点击左上角绿色小锁,点击向右箭头,点击更多信息,点击查看证书,点击详细信息,点击导出。即可导出百度的证书 baiducom.crt
b) 命令查看证书详细信息
openssl x509 -noout -text -in baiducom.crt
详细信息中,有一个字段: X509v3 Basic Constraints: CA: FALSE
该字段指出该证书是否是 CA证书,还是一般性的非 CA 证书。详细描述见 RFC5280#section-4.2.1.9,同时 RFC5280 也详细描述证书工作方式等。
3) 私钥加密,公钥解密!
SSL/TLS是一种工作原理,openssl和mbedtls是SSL/TLS的具体实现,很类似于 TCP/IP协议和socket之间的关系。
我们自己本地使用 makefile.sh 脚本建立一个CA(ca.crt + ca.key),用这个CA给server和client分别颁发证书。
makefile.sh
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of the axTLS project nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
# TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
#
# Generate the certificates and keys for testing.
#
PROJECT_NAME="TLS Project"
# Generate the openssl configuration files.
cat > ca_cert.conf << EOF
[ req ]
distinguished_name = req_distinguished_name
prompt = no
[ req_distinguished_name ]
O = $PROJECT_NAME Dodgy Certificate Authority
EOF
cat > server_cert.conf << EOF
[ req ]
distinguished_name = req_distinguished_name
prompt = no
[ req_distinguished_name ]
O = $PROJECT_NAME
CN = 192.168.111.100
EOF
cat > client_cert.conf << EOF
[ req ]
distinguished_name = req_distinguished_name
prompt = no
[ req_distinguished_name ]
O = $PROJECT_NAME Device Certificate
CN = 192.168.111.101
EOF
mkdir ca
mkdir server
mkdir client
mkdir certDER
# private key generation
openssl genrsa -out ca.key 1024
openssl genrsa -out server.key 1024
openssl genrsa -out client.key 1024
# cert requests
openssl req -out ca.req -key ca.key -new \
-config ./ca_cert.conf
openssl req -out server.req -key server.key -new \
-config ./server_cert.conf
openssl req -out client.req -key client.key -new \
-config ./client_cert.conf
# generate the actual certs.
openssl x509 -req -in ca.req -out ca.crt \
-sha1 -days 5000 -signkey ca.key
openssl x509 -req -in server.req -out server.crt \
-sha1 -CAcreateserial -days 5000 \
-CA ca.crt -CAkey ca.key
openssl x509 -req -in client.req -out client.crt \
-sha1 -CAcreateserial -days 5000 \
-CA ca.crt -CAkey ca.key
openssl x509 -in ca.crt -outform DER -out ca.der
openssl x509 -in server.crt -outform DER -out server.der
openssl x509 -in client.crt -outform DER -out client.der
mv ca.crt ca.key ca/
mv server.crt server.key server/
mv client.crt client.key client/
mv ca.der server.der client.der certDER/
rm *.conf
rm *.req
rm *.srl
将上述代码保存为makefile.sh
做如下修改,终端执行。
- 修改 CN 域中 IP 地址为你主机/设备的 IP 地址
- [可选]加密位数 1024 修改为你需要的加密位数
将会看到:
ca目录:保存ca的私钥ca.key和证书ca.crt
certDER目录:将证书保存为二进制文件 ca.der client.der server.der
client目录: client.crt client.key
server目录:server.crt server.key
$./makefile.sh
删除脚本rmfile.sh:
rm ca/ -rf
rm certDER/ -rf
rm client/ -rf
rm server/ -rf
将上述代码保存为rmfile.sh,终端执行,将会删除产生过的目录和文件:
$./rmfile.sh
我们可在本地使用 CA证书来分别校验由自己颁发的服务器证书 server.crt 和客户端证书 client.crt .
$openssl verify -CAfile ca/ca.crt server/server.crt
$openssl verify -CAfile ca/ca.crt client/client.crt