TLS证书校验

TLS证书校验:对称加密、非对称加密、数字签名、单向校验、双向校验、自签证书、受信任证书

  • 对称加密

用秘钥对信息加密后,可用相同的秘钥进行解密,常用的有DES和RC等系列算法,优点是加密算法执行效率高,缺点是秘钥易泄露,不利于开源,所以常用于本地文件的加密

  • 非对称加密

用公钥对信息加密后,只能用对应的私钥进行解密,或者用私钥对信息加密后,也只能用对应的公钥进行解密,用私钥可生成相应的公钥,用公钥生成不了对应的私钥,使用最广泛的是RSA算法,优点是秘钥管理简单,私钥保留在本地,公钥可随意公布,缺点是非对称加密算法执行效率低,不利于对大量信息进行加解密

  • 数字签名

对任意长度的信息可采用信息摘要算法生成几乎唯一的大整数,所谓几乎就是冲突的概率极低到忽略不计,常用的有MD和SHA等系列算法,数字签名就像指纹一样可唯一标记一个个体,信息一旦被篡改,其摘要也会变

  • 单向校验

TLS是针对基于TCP的应用层协议加密技术,例如FTPS、HTTPS,而基于UDP的应用层协议加密技术由于TLS未处理丢包情况,所以采用基于TLS的DTLS,由于DTLS应用较少,所以暂不研究。
以HTTPS为例,为了充分利用对称加密和非对称加密的优势,通常在秘钥协商阶段采用非对称加密,确定秘钥之后接下来的通信都采用对称加密,而非对称加密过程表面看起来能保证秘钥的安全,但若是客户端和服务器之间通信被黑客劫持,架设一个中间代理,很容易导致正在传输的信息被非法篡改而无法感知,篡改过程如下图所示:tls_fake.png

只有让客户端收到的公钥和服务端发送的公钥一致才能保证信息不被篡改,所以一般会采用第三方的信任机构(CA)签发的证书来保证公钥的一致性,证书主要包含公钥、数字签名、颁发者等信息,证书的校验主要针对数字签名的校验,而数字签名的生成是先对证书中除去签名部分采用SHA算法生成摘要,然后用CA的私钥对其加密,而校验过程则采用CA证书中的公钥对数字签名解密再与SHA算法生成的摘要做对比,以W/S为例,浏览器通常在出厂时,会内置很多第三方根信任证书,chrome和IE则直接用系统的证书管理器,而firefox则采用开源的NAS证书管理,当然也可以采用自签证书来验证,因为自签证书不被信任,所以自签证书需要手动添加到浏览器的证书管理器中,否则浏览器就会告警此网站证书不被信任,试了很多次,导入自签证书后,IE和firefox均未告警,而chrome依然告警,可能是chrome有更严格的验证机制。单向校验的完整过程如下:one_verify.png

  • 双向校验

通常仅校验服务端证书即可,有时需要指定客户端访问就需要双向校验,即服务器与客户端相互校验对方证书,校验过程如下:two_verify.png

  • 自签证书

用个人生成的证书来签发客户端和服务器证书,优点是免费,可用openssl库生成,缺点是自签证书无法内置到浏览器,去除告警只能手动添加

  • 受信任证书

用根证书颁发机构来签发客户端和服务器证书,优点是浏览器内置,缺点是费用较高,腾讯云有免费1年的,但是加了文件验证之后还TM提示我验证失败,巨坑!

  • 实战

以https的双向校验为例,采用openssl生成秘钥及证书,golang实现其验证过程

  1. 首先生成自己的CA秘钥及证书
    openssl genrsa -out ca.key 2048
    openssl req -x509 -new -nodes -key ca.key -subj "/CN=songxu" -days 5000 -out ca.crt
  2. 生成服务端秘钥及用CA来签发其证书
    openssl genrsa -out server.key 2048
    openssl req -new -key server.key -subj "/CN=localhost" -out server.csr
    openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 5000
  3. 生成客户端秘钥及用CA来签发其证书
    openssl genrsa -out client.key 2048
    openssl req -new -key client.key -subj "/CN=localhost" -out client.csr
    openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client.crt -days 5000
  4. 服务端代码
    tls_server.png
  5. 客户端代码
    tls_client.png

完整代码可参考我的github

标签: none

添加新评论