之前做网站的时候,对于用户的模型的建立与实现,有一些简单的了解, 再加上长久以来,在各种网站注册过各种账号,因而产生了一些对密码安全的思考:

  1. 我们的密码安全吗?
  2. 我们在注册账号的时候,会不会暴露一些关键信息?
  3. 我们能不能相信一个网站对于密码的处理方式是安全可信的?

一些声明

首先,我必须声明,以下推论只是建立在我目前的知识体系上,可能有一些安全技术,我现在还不知道,在这种情况下,也许以下推论只是杞人忧天。 其次,本文不是讨论加密算法的优劣,从某种意义上来说,本文讨论的不是技术。

一些知识

为了便于后面推论的阐述,我在这里介绍一些知识背景。

  1. 首先,科普一下目前比较通用的账号注册处理方式。 我们的密码并不是以明文的方式存储在服务器的。当我们注册账号的时候,注册成功之后,我们的密码会经过某些加密算法加密(这一过程通常是不可逆的,采用的算法有MD5SHA-1)。加密的结果类似于一段毫无规则的字符串,例如,对ChrisCheng采用MD5加密之后,会生成814EE337E6209A1A0784DFA28DDA870C,一般情况下,服务器只存储后面这段字符串,前面的密码明文会被丢弃。当我们下次登录的时候,我们输入的密码,会再一次采用相同的加密算法加密,然后将生成的字符串同在服务器中存储的字符串作比较,如果相同,就表明你输入了正确的密码,否则就是错误的密码。所以说,服务器实际上并不是比较密码明文,而是比较密码经过加密的字符串。

  2. 我们在输入账号密码的时候,其输入框都是由对方设计提供的。同样,其内部的处理方式也是各种各样的,似乎没有强制的标准,完全有对方来决定。

一些假设

下文的推论,也是建立在一些基本的假设上。就我个人认为,这些假设基本上是成立的。

  1. 第一个假设:大部分用户,在注册账号的时候会采用同一个密码,或者是某些特定内容的组合 什么样的密码最安全?经常更换的密码最安全。但是经常更换密码可行吗?就我个人看来,不可行。大多数时候,我们都是靠大脑来记密码,且不说网络上的账号,但是普通生活中的账号,要记得密码就有不少,要是经常更换的话,我是不可能记住的。其次,可以不负责任的说,就算不是一码走天下,大部分人的密码也都是采取某些特定内容的组合,比如生日,姓名,住址等,组合方式大部分都是简单的AB,BA等。如果这个假设成立,那么对于大多数人来说,只要知道了他某一个账号的密码,那么其他账号的密码也很容易就能试出来。

  2. 第二个假设:我们假设接收我们密码的对方,其可信程度是未知的 也就是说,我们不能断定接收我们输入的密码的那一方的可信程度。这个假设,基本上也是成立的。对于普通用户而言,我们在输入密码的时候,根本不知道对方会以什么方式处理我们的密码,对于这一点,即使是专业人士,我想也是很难弄清楚的。

  3. 第三个假设:任何一个人只有拿到了我的密码明文,才能登录我的账号。 之所以做这种假设,是要保证,如果有任何一个人拿到了我的密码密文,是不能登录我的账号的。

我的思考

首先,我认为上面的假设是成立的,那么对于用户来说,只要其任意一个账号的密码被别人知道了,那么其所有的账号都是危险的。

密码是怎么泄露的?

  1. 破解密文,破解经过加密的密码,是一个NP困难问题,所以这种方式当然是不考虑的。

  2. 获取明文,密码明文由用户决定,直接获取明文,从某种意义上来说,是一种即困难,也简单。 我们来看看在一次事物中,密码明文的生命周期。

    1. 用户输入密码。
    2. 密码经过一些处理(比如加密),这一过程是可选的。
    3. 密码(或者经过加密的密文)传输到服务器。
    4. 服务器使用密码明文(或密文)。

    以上四个步骤,都有可能造成密码明文泄露,注意,我说的是明文。对于上面四个步骤,用户的可控面,只有在第一步选择是否输入密码,一旦你开始输密码,那么你的密码就有泄露的风险。

    1. 用户输入密码的时候,键盘有可能被监听,但是可以采取软键盘来解决。(前提:对方提供软键盘)
    2. 在传输前,密码可以进行加密,确保传输过程的安全。(前提:对方提供加密)
    3. 密码在传输到对方服务器的过程中,可能被截获。
    4. 密码到达服务器,服务器对密码有完全的控制权,这个密码可能是明文也可能是密文,完全由对方决定。

想象这样一种情况

我做了一个网站,为了某些目的,用户需要在我的网站上注册账号,这样一来,我就可以获取到用户注册时的密码明文,这些用户中,有些人是一码走天下的,也有一些人的密码是某种组合,这样一来,我就获取了这些人的其它账号的密码。而且,最重要的一点是,对于用户来说,我这个网站没有什么不正常的地方。

综上,也许有些人知道在网络上输入密码的时候要小心,但是大部分不知道的是我们在注册一个账号的时候也是很危险的

一些补充

上面我只谈了密码泄露的可能性,也许有些人可能会说,对于一个陌生人,你光知道了密码有什么用,不知道账号照样没辙。这样说的确有道理,但是,值得注意的是,现在越来越多的平台的账号采用了邮箱,比如新浪微博,各大社区站点等。相对于密码,一个人拥有的邮箱的数量应该可能会更少吧,邮箱作为一个公众信息,大部分人都没想过要防止自己的邮箱被别人知道吧。同时,获取用户的邮箱应该算是一件简单的事吧。

如何解决这个问题

针对上面的问题,我觉得有以下几种可能的解决办法:

  1. 前面提到过,上面这些密码泄露的情况,主要是基于接收我们的密码的那一方其可信程度未知这一假设成立为前提的。如果我们能保证对方可信,那么这一问题就不存在了。但是,不幸的是,想要对方可信是很难实现的。似乎没有任何强制标准要求服务提供方必须对用户密码实行加密。大的,有名气的网站还好,一些小网站、论坛,根本就不能保证他们对密码的处理方式。何况,网络是一个自由的世界,每天有成千上万的网站假设起来,你怎么知道你今天登录的网站是可信的?

  2. 如假设所述,另一个解决这个问题的办法是一个账号对应一个密码,不重用密码。现在也有一些软件能帮助用户管理密码。但是,对于使用这些密码管理软件的用户,我需要提醒的是,你得确保这些密码管理软件本身是可信的,有些密码管理软件可能会将你的这些密码信息保存到云端(说白了就是对方服务器),这样一来还是不安全的。

  3. 不能保证对方可信,也不能保证一号一密,就不能保证我们的密码明文不被泄露。所以,下面的几种方法都不能彻底解决这一问题,只能从侧面来降低这个问题带来的影响。

    1. 至少使用两个邮箱,两套密码。一般情况下,涉及到金融交易的网站,比如淘宝、支付宝等,都是可信的,所以可以对这些网站账号使用一套密码,对于一般的常用账号,比如QQ、微信、微博、游戏账号等,使用另一套密码,在这些账号里面,像QQ、微信等,又更加值得关注,因为这些账号本身虽然并没有涉及到财务交易方面,但是作为主要联络工具,也可能被别人利用。最后,对于那些临时性的账号(比如在某论坛下资料要先注册等等),可以采取简单密码123456,或者复杂度低的,反正也没什么大碍。其次,在账号的使用上,对于前两类密码,可以使用一种账号,对于最后一类临时账号,建议采取另一套账号。

    2. 对于提供了双重验证措施的网站,我们应尽量启用双重验证。比如手机验证码登录等等。

能不能通过技术手段实现账号密码可信处理?

一个网站是否可信,大多取决于该网站的管理者,除去这个因素,我们能不能从技术上实现账号密码的可信处理呢?

我想的是能不能完全不提供给对方密码的明文,只提供密文。这样一来,对方只可能拥有密码的密文,再根据前面的第三个假设,也能保证我其他账号的安全。 但是经过思考,发现这种方案似乎只能在注册账号的时候,起到作用,即在注册账号是传给对方密文,对于后续账号的登录验证,却是没有办法的。 因为,首先,对方服务器似乎是不能接受密文来进行验证的(基于第三个假设),同样,用户也不能给服务器(或是对方提供的密码输入界面或是程序)提供明文 (根据前提:不能让服务器获取到我们密码的明文),这样一来,该用什么方法验证用户的身份呢?

注:似乎以前看到的零知识证明可以应用到这个问题上,但是我现在还没有深入研究。