辉哥在学习蚂蚁BAAS系统时,发现了一堆证书或者公私钥名称,包括trustCa,ca.crt,client.crt,client.key,pub.txt,MyPKCS12.p12等等文件,不知道干什么用,内心是奔溃的。后来在阿里专家孙善禄的指导下,输出了《蚂蚁区块链第8课 如何创建新的账户?》搞清楚了user.key和pub.txt文件的作用。
本文着重于介绍SSL/TLS工作原理,带着大家一起学习trustCa,ca.crt,client.key,client.crt,client.key等文件的作用。
什么是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 工作流来一览实现过程。
图一 SSL/TLS 工作流
CA:证书授权中心( certificate authority)。
CA类似于国家出入境管理处一样,给别人颁发护照;也类似于国家工商管理局一样,给公司企业颁发营业执照。
它有两大主要性质:
CA 的证书 ca.crt 和 SSL Server的证书 server.crt 是什么关系呢?
何为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
图二 证书详细工作流
1)申请认证:服务器需自己生成公钥私钥对pub_svr & pri_svr,同时根据 pub_svr 生成请求文件 csr,提交给CA,csr中含有公钥、组织信息、个人信息(域名)等信息。(图一中server.req就是csr请求文件)
2)审核信息:CA通过线上、线下等多种手段验证申请者提供信息的真实性,如组织是否存在、企业是否合法,是否拥有域名的所有权等。
3)签发证书:如信息审核通过,CA会向申请者签发认证文件-证书。
证书包含以下信息:申请者公钥、申请者的组织信息和个人信息、签发机构 CA的信息、有效时间、证书序列号等信息的明文,同时包含一个签名。
签名的产生算法:首先,使用散列函数计算公开的明文信息的信息摘要,然后,采用 CA的私钥对信息摘要进行加密,密文即签名。(图一中生成server.crt)
4)返回证书:client如果请求验证服务器,服务器需返回证书文件。(图一中handshake传回server.crt)
5)client验证证书:client读取证书中的相关的明文信息,采用相同的散列函数计算得到信息摘要,然后,利用对应 CA的公钥解密签名数据,对比证书的信息摘要,如果一致,则可以确认证书的合法性,即公钥合法。客户端然后验证证书相关的域名信息、有效时间是否吊销等信息。
客户端会内置信任CA的证书信息(包含公钥),如果CA不被信任,则找不到对应 CA的证书,证书也会被判定非法。(图一中check可选,我们可以选择不验证服务器证书的有效性)
6)秘钥协商:验证通过后,Server和Client将进行秘钥协商。接下来Server和Client会采用对称秘钥加密。(对称加密时间性能优)(图一中 pre-master/change_cipher_spec/encrypted_handshake_message过程)
7)数据传输:Server和Client采用对称秘钥加密解密数据。
客户端发起请求,以明文传输请求信息,包含版本信息,加密套件候选列表,压缩算法候选列表,随机数,扩展字段等信息,相关信息如下:
支持的最高TSL协议版本version,从低到高依次 SSLv2 SSLv3 TLSv1 TLSv1.1 TLSv1.2,当前基本不再使用低于 TLSv1 的版本;
客户端支持的加密套件 cipher suites 列表, 每个加密套件对应前面 TLS 原理中的四个功能的组合:认证算法 Au (身份验证)、密钥交换算法 KeyExchange(密钥协商)、对称加密算法 Enc (信息加密)和信息摘要 Mac(完整性校验);
支持的压缩算法 compression methods 列表,用于后续的信息压缩传输;
随机数 random_C,用于后续的密钥的生成;
扩展字段 extensions,支持协议与算法的相关参数以及其它辅助信息等,常见的 SNI 就属于扩展字段,后续单独讨论该字段作用。
server_hello, 服务端返回协商的信息结果,包括选择使用的协议版本 version,选择的加密套件 cipher suite,选择的压缩算法 compression method、随机数 random_S 等,其中随机数用于后续的密钥协商;
server_certificates, 服务器端配置对应的证书链,用于身份验证与密钥交换;
server_hello_done,通知客户端 server_hello 信息发送结束;
证书链的可信性 trusted certificate path,方法如前文所述;
证书是否吊销 revocation,有两类方式离线 CRL 与在线 OCSP,不同的客户端行为会不同;
有效期 expiry date,证书是否在有效时间范围;
域名 domain,核查证书域名是否与当前的访问域名匹配,匹配规则后续分析;
client_key_exchange,合法性验证通过之后,客户端计算产生随机数字 Pre-master,并用证书公钥加密,发送给服务器;
此时客户端已经获取全部的计算协商密钥需要的信息:两个明文随机数 random_C 和 random_S 与自己计算产生的 Pre-master,计算得到协商密钥;
enc_key=Fuc(random_C, random_S, Pre-Master)
change_cipher_spec,客户端通知服务器后续的通信都采用协商的通信密钥和加密算法进行加密通信;
encrypted_handshake_message,结合之前所有通信参数的 hash 值与其它相关信息生成一段数据,采用协商密钥 session secret 与算法进行加密,然后发送给服务器用于数据与握手验证;
服务器用私钥解密加密的 Pre-master 数据,基于之前交换的两个明文随机数 random_C 和 random_S,计算得到协商密钥:enc_key=Fuc(random_C, random_S, Pre-Master);
计算之前所有接收信息的 hash 值,然后解密客户端发送的 encrypted_handshake_message,验证数据和密钥正确性;
change_cipher_spec, 验证通过之后,服务器同样发送 change_cipher_spec 以告知客户端后续的通信都采用协商的密钥与算法进行加密通信;
encrypted_handshake_message, 服务器也结合所有当前的通信参数信息生成一段数据并采用协商密钥 session secret 与算法加密并发送到客户端;
客户端计算所有接收信息的 hash 值,并采用协商密钥解密 encrypted_handshake_message,验证服务器发送的数据和密钥,验证通过则握手完成;
开始使用协商密钥与算法进行加密通信。
蚂蚁BAAS隐私链支持SSL/TLS双向认证。
SSL/TLS双向认证流程在client认证完服务器证书后,client会将自己的证书client.crt传给服务器。服务器验证通过后,开始秘钥协商。
我们搭建的SSL/TLS服务器是192.168.111.100,client是192.168.111.101.
client 需要认证 server的合法性,server也需要认证client的合法性!
我们只看 TLSv1.1 的数据包:
蚂蚁BAAS隐私链创建的时候,选择自动生成密钥和证书,则参考前面章节“图二 证书详细工作流”产生了客户端的证书和公私钥。
主要有client.crt,client.key
证书下载
公私钥下载
具体在《蚂蚁区块链第4课 如何创建TEE硬件隐私合约链?》文章做了详细的描述。
用户也可以在如图位置下载跟CA认证和SSL链接相关的所有证书。
证书下载菜单
也可以在这个位置重置客户端证书。
重置合约链证书
如果用户尚未在合约链申请证书,可按照 申请证书 的操作说明去生成和申请证书相关文件。
文件 | 说明 | 来源 |
---|---|---|
ca.crt | 合约链的认证 CA,客户端用来验证合约链服务身份 | 通过 BaaS 平台下载。 |
client.key | RSA 密钥 | 通过 BaaS 提供的 密钥生成工具 生成。 |
client.crt | RSA 证书,与 client.key 是一对 | 使用 BaaS 提供的 密钥生成工具 生成证书请求文件 client.csr,提交请求文件到 BaaS 平台申请证书,申请成功后可下载此 .crt 文件。 |
当客户端需要与 BaaS 平台建立 SSL 连接,需准备三个证书文件:ca.crt
、client.key
、client.crt
。
这个需求发生在使用CLOUD IDE调试智能合约或者集成JS.SDK或者JAVA SDK完成BAAS服务器连接时发生。
参考《蚂蚁区块链第5课 如何配置Cloud IDE证书并进行Solidity智能合约调试?》 完成了ca.crt根证书的导入。依赖client.crt 和 client.key 文件合并生成个人证书文件 MyPKCS12.p12,导入后就可以完成智能合约CloudIDE编辑使用。
如果使用 TEE 硬件隐私合约链,则还需要使用一个 tee_rsa_public_key.pem
文件,此文件从已存在的 TEE 硬件隐私合约链申请,如使用标准的合约链,则不需要使用此文件。
文件 | 说明 | 来源 |
---|---|---|
tee_rsa_public_key.pem | TEE 硬件隐私合约链,节点对外公开的 RSA 公钥文件 | 通过 BaaS 平台下载 |
此文件在JS.SDK调用生成rsa2048时使用。
// 读取 TEE 合约链节点的公钥文件 tee_rsa_public_key.pem
let rsa2048 = {
public: fs.readFileSync('./certs/tee_rsa_public_key.pem')
}
更多内容参考《JS SDK 快速开始》文章。
Java SDK 要与 BaaS 平台建立 SSL 连接,您需准备四个证书文件:CA 机构的根证书(trustCa)、客户端的证书文件(client.crt)、客户端的私钥文件(client.key)以及用户的账户私钥文件(user.key)。
trustCa - 存储 CA 证书的 trustStore -通过 BaaS 平台下载,trustCa 文件密码为 mychain。
使用 Intellij IDEA 创建一个基于 Maven 构建的空项目(Demo)。创建完成后,项目目录结构应如下:
在上图中的 java
目录创建自定义包名,例如:com.example.demo,并将 DemoSample.java
(点击下载 DemoSample.java 文件)中的内容完整拷贝至创建的包中,并将 SDK 必须使用的 client.crt
、client.key
、trustCa
及 user.key
文件放入到 resources
目录中,如下图所示:
![1](http://upload-images.jianshu.io/upload_images/1190574-6072d380e7e36959.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
(1)JS SDK 快速开始 - 准备 SSL 连接文件
https://tech.antfin.com/docs/2/107128
(2)Java SDK 快速开始 - 准备环境
https://tech.antfin.com/docs/2/107721
(2)SSL/TLS协议运行机制的概述
http://www.ruanyifeng.com/blog/2014/02/ssl_tls.html
(3)SSL/TLS 双向认证(一) -- SSL/TLS工作原理
https://blog.csdn.net/ustccw/article/details/76691248
(4)SSL/TLS 双向认证(二) -- 基于mosquittto的MQTT双向认证