从新浪微博和MySQL的password保护机制谈HTTPS/SSL的必要性

尽管业界已经达成共识,在传输用户password等须要保密的信息时,尽可能採用HTTPS/SSL协议传输。

但我们还是能够看到少数没实用HTTPS/SSL加密的站点或应用。

新浪微博的登录页面和MySQL是两个样例。接下来我们具体分析它们的password传输和保存机制。

新浪微博

新浪微博的登录页面的URLhttp://www.weibo.com/login。从这能够看出新浪微博的登录页面没有採用HTTPS来传输用户的password。

假设我们对登录相关的代码感兴趣。我们能够用浏览器的调试功能看到例如以下图所看到的的代码:


从这段代码我们能够猜出新浪微博的登录步骤例如以下:

  1. 新浪微博的client往server端发送一个连接请求;

  2. server端响应client的请求,返回的信息里包括当前时间(图中的servertime)和一个随机数(图中的nonce)。

  3. client对用户的password进行加密,然后再发送给server端验证。加密的算法是SHA1(SHA1(SHA1(Password))+ salt)。当中的salt是从server返回的时间和随机数。

我们看不到server端的代码,但大致能够猜出数据库里存的是明文password的一次或者两次SHA1加密之后的哈希值。

为了防止被彩虹表法破解,存两次SHA1加密的哈希值的可能性要高一些。

server端在验证password的时候先从数据库里读出password的哈希值。server端知道自己发给client的时间和随机数,于是它把password的哈希值和时间以及随机数拼接起来再用SHA1算法计算新的哈希值。

最后它比較计算出来的哈希值和从client接收到的用户password加密后的哈希值。假设两个哈希值同样,则登录验证成功。

破解方法

新浪微博这种password保护机制还是存在非常大风险。

一旦存储用户password的数据库被黑客侵入,那么黑客非常easy就能用他人的password登录。

黑客侵入数据库之后。他就知道他人password的两次SHA1算法的哈希值。接着他能够写一个假的client,然后通过假的client欺骗server端返回当前时间和一个随机数。接下来把server端返回的信息当作盐和数据库里读取的password的哈希值拼接到一起再调用SHA1算法算出新的哈希值,最后把这个哈希值发送给server端。

因为这样生成的哈希值符合新浪微博password验证的协议,server端会觉得password有效。

因此黑客尽管没有破解他人的password。但他却在侵入数据库之后用他人的password登录。

MySQL

MySQL的password保护机制和前面的新浪微博的机制有相似之处。

在数据库表格mysql.userPassword列中。password存的是用SHA1算法两次加密之后的哈希值。client和server端的通讯协议包括例如以下几个步骤:

  1. MySQLclient(比方mysql.exe)发起连接请求;

  2. MySQLserver端(mysqld.exe)返回一个随机字符串scramble

  3. MySQLclient接收到scramble后。进行例如以下计算并把token发给server端:

    1. stage1_hash = SHA1(password),当中password是用户输入的明文password。

    2. token = SHA1(scramble +SHA1(stage1_hash)) XOR stage1_hash

server端在接收到加密之后的passwordtoken之后。採取例如以下步骤验证password是否有效:

  1. stage1_hash' = token XOR SHA1(scramble +mysql.user.Password)

  2. 计算SHA1(stage1_hash')的值。并和mysql.user.Password作比較。假设两者同样则password有效。

假设对MySQL的源码感兴趣,对应的代码在.mysql-5.5.37sqlpassword.c能够找到。

我们能够看出MySQL的password在传输过程中client与server端的协议比新浪微博的要复杂。这种优点是假设黑客入侵了mysql.user表拿到了两次SHA1加密的哈希值,他也没有办法伪装他人。这是因为在通讯协议的第3步在计算token的过程中,须要对password作一次SHA1加密的哈希值。而在mysql.user表中。仅仅有对password作两次SHA1的哈希值。

破解方法

尽管MySQL的机制比新浪微博的要安全一些,但它仍然存在安全隐患。这个机制的短板在于password的存储。存储password的两次SHA1算法的哈希值并不能有效防止彩虹表法破解。

非常多黑客手上都有SHA1算法哈希值的彩虹表。他们仅仅要把这种彩虹表里的哈希值再作一次SHA1加密就能够了。

MySQL採用这个机制也能够理解。

假设黑客能够侵入mysql.user表格。那么他自然也能侵入MySQL数据库中的其它表格。

通常黑客破解的password的目的是盗取他人的数据。也就是黑客一旦侵入了mysql.user表格,那么他无需破解password也就能盗取数据了。

MySQL採用上述password保护机制有它的理由。其它系统假设也採用同样的机制,就要细致考虑当中的安全隐患了。

小结

一个系统的password保护机制是否安全取决于两个方面,即password传输的安全性和password存储的安全性。新浪微博和MySQL都没有採用HTTPS/SSL传输password。为了防止黑客在password传输过程中窃听password。它们仅仅能在传输过程中加盐然后用SHA1算法加密。因为password在传输过程中须要加盐,为了能够正常验证password,因此在存储password时仅仅能存储没有加盐的SHA1算法的哈希值。

因此password的存储成为整个机制的短板。

笔者曾写过一篇博客讨论怎样安全地存储password。感兴趣的读者请參考http://blog.csdn.net/cadcisdhht/article/details/19282407

我们没有必要在抛弃HTTPS/SSL的前提下试图去设计更加复杂的加密算法或者通讯协议。上述提到的两个方案是新浪微博和MySQL的程序猿们花了大量精力设计出来的机制,尚且还有明显的漏洞。我不觉得每一个程序猿都有自信说自己比新浪微博或者MySQL的程序猿更加优秀。

HTTPS/SSL在传输过程中用证书加密。不须要加盐来提高传输的安全性。这样在存储password的时候就能够採用加盐的机制,比方简单地採用加盐的SHA1算法。也能够採用Bcrypt或者PBKDF2。如此以来,在password的传输和存储两个环节都取得非常好的安全性。

假设安全性对一个系统是至关重要的因素,那么就採用HTTPS/SSL吧。

尽管部署HTTPS/SSL的系统有些麻烦,申请可信赖的CA的证书还要花钱,但和安全漏洞的潜在风险相比这些代价还是值得的。



原文地址:https://www.cnblogs.com/jzssuanfa/p/6855243.html