先说 HTTPS, HTTPS在 TCP 和 HTTP 协议之间添加了一层用来加密(加密原理就不说了),上层不用考虑具体下层的实现,服务器(发送页面,AJax通信等)不用考虑底层的实现,也就是说你写 PHP 的代码,所有数据都是加密发送出去的,可以保证所有的数据不被窃听不被篡改,所以你可以不用考虑任何与加密相关的事情就可以认为通信是安全的。
这种安全仅仅是指防止链路上的窃听和篡改,只是说服务器和客户间的路由器无法篡改和解密两台机器间的通信数据,路由器做的只能是转发。 HTTPS并不保证在服务器或是客户的电脑上数据的安全。就是说,你电脑上的恶意软件依旧可以窃听和篡改数据。 一种可能需要我们注意的情况是,一个HTTPS 页面,引用了一个非 HTTPS 的 JS(或者其他页面), 那么这个 JS 就是不安全的,有可能被篡改并在客户的浏览器里执行,而这个 JS 是可以访问这个页面所有的数据的,此时如果有敏感数据被这个 JS 读取并发送出去也是可能做到的。
HTTP 所有报文都是明文发送,两台电脑间的所有数据都可以被中间的路由看到,并且可以随意的修改,因此他是不安全的。涉及到密码的传输,如果是仅仅是密码验证的话可以使用简单的方式做到比较安全。 具体做法是,首先选一个hash函数,比如sha1。 服务器生成一个随机数n1(随机字符串),客户端也生产一个随机数n2,相互发送给对方。 然后,客户端求得sha1("密码"+"n1"+"n2") 之后发送给服务器,服务器使用相同的算法计算这个值,如果相同则验证成功。(当然,服务器上一般不明文保存密码,但是这个没有关系)。 生成随机数的目的是防止重放攻击。
如果服务器,客户端和中间的恶意路由(或者其他监听者)一开始知道的信息都一样,那么无论服务器和客户端怎么通信都不会获知额外的恶意路由不知道的信息,此时,怎么通信都是不安全的。 加密就是使用“坏人”不知道的一些信息,利用这一部分信息来加密。 HTTPS就是事先服务器生成一对公钥,“坏人”无法获知私钥的信息(“坏人”知道的信息少),用户在电脑上保存并且绝对信任这个公钥而实现的加密。如果“坏人”事先获知了服务器的私钥,或是用户电脑信任了“坏人”已知私钥的公钥,那么HTTPS也是不安全的。所以,如 @奔跑的香蕉 所说的那样,有服务器生成公钥发送给浏览器也是可以完成对敏感数据加密的。