beizili

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

首先什么是HTTP协议?

http协议是超文本传输协议,位于tcp/ip四层模型中的应用层;通过请求/响应的方式在客户端和服务器之间进行通信;但是缺少安全性,http协议信息传输是通过明文的方式传输,不做任何加密,相当于在网络上裸奔;容易被中间人恶意篡改,这种行为叫做中间人攻击;

加密通信:

为了安全性,双方可以使用对称加密的方式key进行信息交流,但是这种方式对称加密秘钥也会被拦截,也不够安全,进而还是存在被中间人攻击风险;
于是人们又想出来另外一种方式,使用非对称加密的方式;使用公钥/私钥加解密;通信方A发起通信并携带自己的公钥,接收方B通过公钥来加密对称秘钥;然后发送给发起方A;A通过私钥解密;双发接下来通过对称秘钥来进行加密通信;但是这种方式还是会存在一种安全性;中间人虽然不知道发起方A的私钥,但是可以做到偷天换日,将拦截发起方的公钥key;并将自己生成的一对公/私钥的公钥发送给B;接收方B并不知道公钥已经被偷偷换过;按照之前的流程,B通过公钥加密自己生成的对称加密秘钥key2;发送给A;
这次通信再次被中间人拦截,尽管后面的通信,两者还是用key2通信,但是中间人已经掌握了Key2;可以进行轻松的加解密;还是存在被中间人攻击风险;

解决困境:权威的证书颁发机构CA来解决;

  1. 制作证书:作为服务端的A,首先把自己的公钥key1发给证书颁发机构,向证书颁发机构进行申请证书;证书颁发机构有一套自己的公私钥,CA通过自己的私钥来加密key1,并且通过服务端网址等信息生成一个证书签名,证书签名同样使用机构的私钥进行加密;制作完成后,机构将证书发给A;

  2. 校验证书真伪:当B向服务端A发起请求通信的时候,A不再直接返回自己的公钥,而是返回一个证书;
    说明:各大浏览器和操作系统已经维护了所有的权威证书机构的名称和公钥。B只需要知道是哪个权威机构发的证书,使用对应的机构公钥,就可以解密出证书签名;接下来,B使用同样的规则,生成自己的证书签名,如果两个签名是一致的,说明证书是有效的;
    签名验证成功后,B就可以再次利用机构的公钥,解密出A的公钥key1;接下来的操作,就是和之前一样的流程了;

  3. 中间人是否会拦截发送假证书到B呢?
    因为证书的签名是由服务器端网址等信息生成的,并且通过第三方机构的私钥加密中间人无法篡改; 所以最关键的问题是证书签名的真伪;

  4. https主要的思想是在http基础上增加了ssl安全层,即以上认证过程;

# 首先,打开 Keychain Access,找到上述证书,拖拽出来
# 重命名为 root.cer

# 转换 DER 到 PEM 格式
$ openssl x509 -inform der -in root.cer -out root.pem

# 查看证书的签名,可以看到签名所使用的的 hash 算法是 sha1
$ openssl x509 -in root.pem -text -noout -certopt ca_default -certopt no_validity -certopt no_serial -certopt no_subject -certopt no_extensions -certopt no_signame
    Signature Algorithm: sha1WithRSAEncryption
         1c:1a:06:97:dc:d7:9c:9f:3c:88:66:06:08:57:21:db:21:47:
         f8:2a:67:aa:bf:18:32:76:40:10:57:c1:8a:f3:7a:d9:11:65:
         8e:35:fa:9e:fc:45:b5:9e:d9:4c:31:4b:b8:91:e8:43:2c:8e:
         b3:78:ce:db:e3:53:79:71:d6:e5:21:94:01:da:55:87:9a:24:
         64:f6:8a:66:cc:de:9c:37:cd:a8:34:b1:69:9b:23:c8:9e:78:
         22:2b:70:43:e3:55:47:31:61:19:ef:58:c5:85:2f:4e:30:f6:
         a0:31:16:23:c8:e7:e2:65:16:33:cb:bf:1a:1b:a0:3d:f8:ca:
         5e:8b:31:8b:60:08:89:2d:0c:06:5c:52:b7:c4:f9:0a:98:d1:
         15:5f:9f:12:be:7c:36:63:38:bd:44:a4:7f:e4:26:2b:0a:c4:
         97:69:0d:e9:8c:e2:c0:10:57:b8:c8:76:12:91:55:f2:48:69:
         d8:bc:2a:02:5b:0f:44:d4:20:31:db:f4:ba:70:26:5d:90:60:
         9e:bc:4b:17:09:2f:b4:cb:1e:43:68:c9:07:27:c1:d2:5c:f7:
         ea:21:b9:68:12:9c:3c:9c:bf:9e:fc:80:5c:9b:63:cd:ec:47:
         aa:25:27:67:a0:37:f3:00:82:7d:54:d7:a9:f8:e9:2e:13:a3:
         77:e8:1f:4a

# 提取签名内容到文件中
$ openssl x509 -in root.pem -text -noout -certopt ca_default -certopt no_validity -certopt no_serial -certopt no_subject -certopt no_extensions -certopt no_signame | grep -v 'Signature Algorithm' | tr -d '[:space:]:' | xxd -r -p > root-signature.bin

# 提取根证书中含有的公钥
$ openssl x509 -in root.pem -noout -pubkey > root-pub.pem

# 使用公钥解密签名
$ openssl rsautl -verify -inkey root-pub.pem -in root-signature.bin -pubin > root-signature-decrypted.bin

# 查看解密后的内容
# 可以看到,签名中存储的 hash 值为 E35E...13A8
$ openssl asn1parse -inform DER -in root-signature-decrypted.bin
    0:d=0  hl=2 l=  33 cons: SEQUENCE
    2:d=1  hl=2 l=   9 cons: SEQUENCE
    4:d=2  hl=2 l=   5 prim: OBJECT            :sha1
   11:d=2  hl=2 l=   0 prim: NULL
   13:d=1  hl=2 l=  20 prim: OCTET STRING      [HEX DUMP]:E35EF08D884F0A0ADE2F75E96301CE6230F213A8

# 接下来我们计算证书的 hash 值

# 首先提取证书的 body
# 因为证书中含有签名,签名是不包含在 hash 值计算中的
# 所以不能简单地对整个证书文件进行 hash 运算
$ openssl asn1parse -in root.pem -strparse 4 -out root-body.bin &> /dev/null

# 计算 sha1 哈希值
$ openssl dgst -sha1 root-body.bin
SHA1(root-body.bin)= e35ef08d884f0a0ade2f75e96301ce6230f213a8
posted on 2021-06-02 17:37  被子里  阅读(57)  评论(0编辑  收藏  举报  来源