zoukankan      html  css  js  c++  java
  • 快速了解公钥、私钥与证书

    最近有需要了解这方面的知识,于是网上看了一些资料,这里记录2个比较通俗易懂的介绍,对普通的加解密和整个http数据传输流程理解很有帮助。

    转载于:

    作者:David Youd

    翻译:阮一峰

    英文原文网址:http://www.youdzone.com/signature.html

    中文翻译网址:http://www.blogjava.net/yxhxj2006/archive/2012/10/15/389547.html

    一次看懂 Https 证书认证

    数字签名是什么?

    img

    鲍勃有两把钥匙,一把是公钥,另一把是私钥。

    img

    鲍勃把公钥送给他的朋友们----帕蒂、道格、苏珊----每人一把。

    img

    苏珊要给鲍勃写一封保密的信。她写完后用鲍勃的公钥加密,就可以达到保密的效果。

    img

    鲍勃收信后,用私钥解密,就看到了信件内容。这里要强调的是,只要鲍勃的私钥不泄露,这封信就是安全的,即使落在别人手里,也无法解密。

    img

    鲍勃给苏珊回信,决定采用"数字签名"。他写完后先用Hash函数,生成信件的摘要(digest)。

    img

    然后,鲍勃使用私钥,对这个摘要加密,生成"数字签名"(signature)。

    img

    鲍勃将这个签名,附在信件下面,一起发给苏珊。

    img

    苏珊收信后,取下数字签名,用鲍勃的公钥解密,得到信件的摘要。由此证明,这封信确实是鲍勃发出的。

    img

    苏珊再对信件本身使用Hash函数,将得到的结果,与上一步得到的摘要进行对比。如果两者一致,就证明这封信未被修改过。

    img

    复杂的情况出现了。道格想欺骗苏珊,他偷偷使用了苏珊的电脑,用自己的公钥换走了鲍勃的公钥。此时,苏珊实际拥有的是道格的公钥,但是还以为这是鲍勃的公钥。因此,道格就可以冒充鲍勃,用自己的私钥做成"数字签名",写信给苏珊,让苏珊用假的鲍勃公钥进行解密。

    img

    后来,苏珊感觉不对劲,发现自己无法确定公钥是否真的属于鲍勃。她想到了一个办法,要求鲍勃去找"证书中心"(certificate authority,简称CA),为公钥做认证。证书中心用自己的私钥,对鲍勃的公钥和一些相关信息一起加密,生成"数字证书"(Digital Certificate)。

    img

    鲍勃拿到数字证书以后,就可以放心了。以后再给苏珊写信,只要在签名的同时,再附上数字证书就行了。

    img

    苏珊收信后,用CA的公钥解开数字证书,就可以拿到鲍勃真实的公钥了,然后就能证明"数字签名"是否真的是鲍勃签的。

    下面,我们看一个应用"数字证书"的实例:https协议。这个协议主要用于网页加密。

    img

    首先,客户端向服务器发出加密请求。

    img

    服务器用自己的私钥加密网页以后,连同本身的数字证书,一起发送给客户端。

    客户端(浏览器)的"证书管理器",有"受信任的根证书颁发机构"列表。客户端会根据这张列表,查看解开数字证书的公钥是否在列表之内。

    img

    如果数字证书记载的网址,与你正在浏览的网址不一致,就说明这张证书可能被冒用,浏览器会发出警告。

    如果这张数字证书不是由受信任的机构颁发的,浏览器会发出另一种警告。

    img

    TLS

    传输层安全性协定 TLS(Transport Layer Security),及其前身安全套接层 SSL(Secure Sockets Layer)是一种安全协议,目的是为网际网路通信,提供安全及数据完整性保障。

    image-20191022202706325

    如图,TLS 在建立连接时是需要

    1. 客户端发送 ClientHello(包含支持的协议版本、加密算法和 随机数A (Client random))到服务端
    2. 服务端返回 ServerHello、公钥、证书、随机数B (Server random) 到客户端
    3. 客户端使用CA证书验证返回证书无误后。生成 随机数C (Premaster secret),用公钥对其加密,发送到服务端
    4. 服务端用 私钥 解密得到 随机数C (Premaster secret),随后根据已经得到的 随机数ABC生成对称密钥(hello的时候确定的加密算法),并对需要发送的数据进行对称加密发送
    5. 客户端使用对称密钥(客户端也用随机数ABC生成对称密钥)对数据进行解密。
    6. 双方手持对称密钥 使用对称加密算法通讯

    而这一流程 服务端的证书 是是至关重要的。

    证书

    证书用来证明公钥拥有者身份的凭证

    首先我们需要知道 证书是怎么来的。

    数字证书一般由数字证书认证机构签发,需要

    • 申请者通过非对称加密算法(RSA) 生成一对公钥密钥,然后把需要的申请信息(国家,域名等)连同公钥发送给 证书认证机构(CA)
    • CA构确认无误后通过消息摘要算法(MD5,SHA) 生成整个申请信息的摘要签名M, 然后 把 签名M和使用的摘要算法CA自己的私钥 进行加密

    证书包含了

    • 公钥
    • 证书拥有者身份信息
    • 数字证书认证机构(发行者)信息
    • 发行者对这份文件的数字签名及使用的算法
    • 有效期

    证书的格式和验证方法普遍遵循 X.509 国际标准。

    image

    证书认证机构(CA)

    数字证书认证机构(英语:Certificate Authority,缩写为CA),也称为电子商务认证中心、电子商务认证授权机构,是负责发放和管理数字证书的权威机构,并作为电子商务交易中受信任的第三方,承担公钥体系中公钥的合法性检验的责任。

    其实任何个体/组织都可以成为CA(自签证书),但是你发发布的证书客户端是不信任的,也是就前文提及的需要权威。比如 Symantec、Comodo、Godaddy、Digicert

    客户端信任这些CA,就会在其本地保持这些CA的 根证书root certificate),根证书是CA自己的证书,是证书验证链的开头。
    根证书没有机构(已经是权威了)再为其做数字签名,所以都是自签证书。

    CA会通过 中介证书(intermediate-certificate) 替代根证书的去做服务器端的证书签名,确保根证书密钥绝对不可访问。

    Godaddy 给出了解释

    What is an intermediate certificate?
    https://sg.godaddy.com/help/what-is-an-intermediate-certificate-868

    证书信任链

    前文提到,在向CA 申请证书时是需要 CA的私钥 去对整个证书的签名摘要做非对称加密的,也就是证书是可以通过 CA的公钥 去解密得到证书的签名摘要的。
    当我们再次用 相同的摘要算法(证书里面有保存所使用的算法)对整个证书做签名,如果得到的签名和证书上的签名是一致的,说明这个证书是可信任的。

    同理,中介证书 也是可以被这样的方式证明其可信任。这样的一整个流程称为 信任链(Chain of trust)。

    就是我绝对相信你(A>B);你绝对相信他(B>C);等于我绝对相信他(A>C)

    以下是整个流程:

    信任链.gif

    1. 客户端得到服务端返回的证书,通过读取得到 服务端证书的发布机构(Issuer)
    2. 客户端去操作系统查找这个发布机构的的证书,如果是不是根证书就继续递归下去 直到拿到根证书
    3. 根证书的公钥解密验证 上一层证书的合法性,再拿上一层证书的公钥去验证更上层证书的合法性;递归回溯。
    4. 最后验证服务器端的证书是 可信任 的。
  • 相关阅读:
    Java基础算法--排序
    Java基础之String类的细节问题
    Java数据结构四之——二叉树的前、中、后序遍历
    动态规划之----最长公共子序列(LCS)
    最长公共子串问题
    makefile学习笔记
    使用正则表达式,去除C++的注释
    gbk字库音序对照表
    Fsharp 类中的空字段
    使用FSharp 探索Dotnet图像处理功能2--均衡灰度
  • 原文地址:https://www.cnblogs.com/xiaoqiangink/p/14106858.html
Copyright © 2011-2022 走看看