2.4 ssl 原理概述
非对称加密
我有一个 私钥 和一个对应的 公钥,私钥由我自己保存,不能泄露给其他人,公钥对外公开。
这一对私钥和公钥的特性是:
- 经公钥加密的信息,只能通过私钥解密
- 私钥可以对信息生成签名,公钥可以验证签名,从而确定:
- 这个信息是公钥对应的私钥签名的
- 信息的内容没有被修改
由此延伸出 2 个用途:
- 如果有人想给我发信息,但是不想让除我们外的其他人知道这个信息,可以在发送之前用我的公钥加密信息,然后发送加密后的信息。这样只有持有私钥的我才能解密信息,其他人即使拦截到加密的信息也无法解密。
- 如果我想对外宣发一个信息,同时不想让任何人冒充我宣发虚假信息,不想让任何人篡改我宣发的信息,可以在发布信息之前用我的私钥对信息进行签名。这样所有持有我公钥的人都可以通过签名确认信息的确是我发布的,并且没有经过篡改。
但是还存在一个问题,就是有人可能会冒充我散发假的公钥,那么其他人如何才能确认他们持有的公钥的确是我的公钥呢?
证书
我对外提供包含我公钥和身份信息的证书
我之前都是直接对外提供我的公钥,现在我想换一种方式,对外提供我的证书,证书里包含我的公钥,同时还包含我的身份信息,例如我的名字,所属的国家,组织,特别重要的是,如果我对外提供服务,可以把我提供服务的域名或者 ip 作为我身份信息的一部分。
这样用户可以从我的服务获取证书,同时检查证书里身份信息的域名和当前提供服务的域名是否一致,如果不一致,则代表有其他人假冒我提供我的证书。
这样可以解决解决一部分问题,但是仍然不能防止有人拦截并修改我返回的响应,将证书里的公钥替换成他的公钥。
CA
找 CA 对我的证书进行签名
怎么样可以防止其他人拦截并篡改我的证书内容,这个要求可以用私钥签名来做。我可以对我的证书进行签名,这样如果证书内容发生改变,就没办法和签名对应了。
这里当然不能用我的私钥签名(不要忘了这里证书的目的就是为了让其他人正确的获取我的公钥,在没有获取我的公钥之前,其他人无法验证我的私钥签名),但是我可以找一个权威的第三方 CA 对我证书进行签名。
前提是所有人都要信任 CA
这里有一个 前提是所有人都要信任 CA,即提前正确的获取到 CA 的公钥(即证书):
- 浏览器/操作系统会内置一些权威 CA 的证书(CA 的公钥,身份信息,(其他CA的签名))
- 可以手动添加/指定自己信任 CA 的证书(CA 的公钥,身份信息,(其他CA的签名))
- CA 信任链: CA 的证书同样可以让其他 CA 对其进行签名,这样如果 CA 1 不够权威,没有内置在浏览器/操作系统中,那么 CA 1 可以找更权威的 CA 对自己进行签名,这条 CA 签名的链条可以一直延伸下去。信任链的终点被称为 root CA,它是自签名的证书。
CA 需要确认我的公钥就是我的公钥
CA 在对我的证书进行签名之前,要验证我的身份,一般是这样做的:
- 例如我对外提供一个网站服务,那么我证书身份信息也要有这个网站地址,CA 会要求我在我的网站增加一个文本链接,文本内容是 CA 随机生成的内容,我在网站增加了这个文本后,CA 就可以确认我的确是这个网站的拥有者。
我对外公布 CA 签名后的证书(包含了我的公钥,身份信息,CA 签名)
CA 签名之后,我可以对外公布 CA 签名后的证书:
- 其他人可以通过对比证书中的身份信息和获取证书的服务地址确认这个证书的确是我的证书
- 同时通过 CA 签名可以验证证书没有被拦截篡改过
这样其他人就可以正确的获取我对外公布的公钥了