https加密原理
客户端 C,服务端S,中间黑客M,密钥Key,公钥pk(public key),私钥ik(induvial key)。【简写和对应单词是我自己造的,不是标准的,大家看着理解过程就行】
-
思路1:
C向S请求数据,S发一个Key,C收到,双方以后加密解密用这个key来加密解密即可。
req C ============> S key C <============ S 用key加密后的信息 C ================> S 用key加密后的信息 C <============ S
问题:
传输密钥的时候是明文的,M可以获取key,从而知道双方的通信内容
-
思路2:
使用非对称加密算法RSA。
- 可以获得pk和ik
- pk可以公开,ik必须保管好
- ik加密 -> pk解密
- pk加密 -> ik解密
- 上述c和d必须遵循。
C向S请求数据,C用RSA生成Cik和Cpk,C把自己的Cpk发给S,S用RSA生成Sik和Spk。S把自己的Spk和数据通过Cpk加密之后发给C,(期间无人能得到加密内容,因为S把数据用Cpk加密了,只有通过Cik才能解密获得发送的内容)。
req, Cpk C(Cik, Cpk) ===============> S(收到Cpk) Spk C(收到Spk) <============= S(Sik, Spk, Cpk) 用Spk加密后的信息 C ================> S(用Sik解密) 用Cpk加密后的信息 C(用Cik解密) <============= S
问题看似解决了。
存在的问题:
中间人攻击:
C在向S发送Cpk时,M截获本次C的请求获得Cpk,M用RSA生成Mik和Mpk,直接用Cpk加密数据返回Mpk。(应该可以通过ip代理实现伪装成S,这块我也不是很清楚)。
这样的话,C得到的就是Mpk,C可以通过自己的Cik获得数据和Mpk,之后发送数据使用的都是Mpk加密后的数据,那么M每次都可以获得Cpk,从而知道C想发送的内容,拦截真正的发送,把自己想返回的内容返回给C。
M如果想要向服务器发送数据的话,由于知道C的ip,挂上C的ip名号,发送自己的Mpk和Mik,那么服务器也是会错把M当成C。
req, Cpk (截胡,收到Cpk,修改Cpk为Mpk) req, Mpk C(Cik, Cpk) =============== M ==============================> S(收到Mpk) Mpk (截胡,收到Spk,修改Spk为Mpk) C(收到Spk) <============= M ============================== S(Sik, Spk, Mpk) 用Mpk加密后的信息 (用Mik解密,修改,再用Spk加密) (收到的数据已经被改了) C =============== M =============================> S(用Sik解密) (用Mik解密,修改,再用Cpk加密) 用Mpk加密后的信息 C(用Cik解密) <============== M =============================S
-
思路三:
由于RSA每次发消息都要加密解密慢,而且也有中间人攻击。
可以这样,每次通信前先通过RSA发送对称加密的密钥,这样快,比每次通过RSA私钥加密快多了。
但是 中间人问题 还没有解决。
req, Cpk C(Cik, Cpk) ===============> S(收到Cpk) Spk C(收到Spk) <============= S(Sik, Spk, Cpk) 用Spk加密后的对称密钥NIK C ================> S(用Sik解密) 通信用NIK C(用Cik解密) <================ S
-
思路四:
S利用一个信任的第三方认证机构CA,CA有自己的Cik,Cpk,CA把S发来的公钥加密形成数字签名,返回给S,S把返回的数字签名和自己的公钥以及相关信息组合成证书。
证书Cer:对于一个数据提取特征进行加密,得到一个数字签名,把数据本身和数字签名绑定到一起成为证书。
Spk CA <============================== S(给你公钥) 用(CAipk加密并且把数字签名返回) CA ==============================> S req, Cpk (截胡,收到Cpk,修改Cpk为Mpk) req, Mpk C(Cik, Cpk) =============== M ==============================> S(收到Mpk) Mpk (截胡,收到Cer,修改Spk为Mpk) 组合发送Cer C <============= M ============================== S(Sik, Spk, Mpk) (C:收到Cer) 给我公钥 C ==============> CA Cpk C <============== CA C(用Cpk解密刚才收到的Cer的数字签名,把S发来的信息通过商量的hash算法hash计算出值,看二者是否相同,不同,对方不可信)。
Spk CA <============================== S(给你公钥) 用(CAipk加密并且把数字签名返回) CA ==============================> S req, Cpk C(Cik, Cpk) =============================================> S(收到Cpk) Mpk 组合发送Cer C <=========================================== S(Sik, Spk, Cpk) (C:收到Cer) 给我公钥 C ==============> CA Cpk C <============== CA C(用Cpk解密刚才收到的Cer的数字签名,把S发来的信息通过商量的hash算法hash计算出值,看二者是否相同,相同,对方可信)。 C ===========================================> S(Sik, Spk) (用Spk加密对称密钥INK,发给Spk) 用对称密钥发数据就行了 C(INK) <=========================================== S(Sik, Spk, INK)
C获取CA的公钥的时候可能会被发起中间人攻击,所以基本上浏览器都把一些公认的CA的公钥内置了。
(其实还有问题,因为客户端没有证书的,所以你怎么知道对方是对方?难道你想让客户端买证书?花钱?下一次研究用户的认证,敬请期待。ps:本文如有错,请指出,谢谢)