不要再强迫我设置复杂密码

我最近读的一篇博文(伯乐在线注:请看本文最后),是关于强制使用更复杂的密码。原作者说这是为了更安全,但我认为这些技术不是最好的方式,比起「实用」来说,显得很麻烦。

问题

你想实施更安全的密码,我懂。但是,

请停止强迫我使用你那糟糕的密码规则 🙁

不让这篇文章那么严肃,我在试图做到这一点。我只是因为那篇文章有了灵感写下我的想法,不是针对作者。总之我是在和每一个在自己的网站和服务器使用这些密码规则的人讲话。我讨厌这些类型的规则:

'password' => [
    'required',
    'confirmed',
    'min:8',
    'regex:/^(?=S*[a-z])(?=S*[A-Z])(?=S*[d])S*$/',
];

密码必须包含 1 个大写字母,1 个小写字母和数字。

有了这样的一个规则,密码 Abcd1234 会通过你的有效性检测,但是 mu-icac-of-jaz-doad 不会。

我知道你大概是想让人们使用随机字符密码,像 i%Mk3c4n,但是你的规则实际上并没有这样执行,这些密码是个麻烦事而且不安全,除非它们足够长——使得它们成为更麻烦的事。打出这些密码很痛苦,尤其是在那些你没有安装密码管理器的手机和计算机上。

其次,使用不安全密码的人依旧会使用愚蠢的密码(比如 Loverboy1964),所以你没有帮助任何人。

停止强迫我使用你专制的规则并鼓励其他人这么做——我的密码是更好呢。

例子

那位博主允许使用的 2 个密码:

ecf66cbb9a_7cc829d3gw1f0bhdnvdxyj20z40mg77r

92e608a77b_7cc829d3gw1f0bhdojp0ej20zk0o0adw

下面这两个是那位博主不允许使用的密码:

3db8c04b92_7cc829d3gw1f0bhdp3w2vj20zg0ni424

07d907f9f8_7cc829d3gw1f0bhdpqnztj20z80ni428

解决方案

我不知道,但是如果你真的想要执行一些比此列表上的密码更安全的东西,那就不要强制不必要的复杂模式。你的验证规则,还是会让人继续用的原密码中的大部分,只是增加一个大写字母,或两三个数字。

(注1:此处提到的密码列表,里面都是 123456 、password、qwerty 之类的「愚蠢密码」)

相反,为什么不提高密码所需的最小长度,禁止 3 位或更长的数字序列 /[0-9]{3,}/?

你可以在那之后往前走一小步,不允许同样的字符在一行(相邻)重复两次以上 /(.)1{2,}/,而且还没有太多的麻烦。

这将消除大部分的困扰,并不会不必要地限制您的用户密码选择。

更新

更好的是,为什么不忘记所有这些规则,只使用一个最小密码强度要求。

fc81ac093e_7cc829d3gw1f0bhdqbiphj20ac022jr9

来自 reddit 网友 sarciszewski 的建议:

我不明白为什么那么多人不用 Zxcvbn。

我们并不特别关心你的密码包含了什么,只要密码强度估计量足够好就行。想要用2000个’A’构成一个ASCII penis来检测,zxcvbn 不会提醒你密码不包含小写字母不能使用而让你失望。

相关漫画

密码强度 (xkcd)

fc5ab6eb06_7cc829d3gw1f0bhdr2msvj20kk0gpn1i

 


《在 Laravel 中强制复杂密码的建议》英文原文

根据简单优雅的 Laravel 文档,我将快速介绍如何促进用户使用更好的密码。通过 Authentication 的标准文档,我们用一个注册表单来说明。在 Laravel 的 AuthController 中,我稍作了修改。

(伯乐在线补注:Laravel 是一个 PHP Web 开发框架。)

    protected function validator(array $data)
    {
        $messages = ['password.regex' => "Your password must contain 1 lower case character 1 upper case character one number"];
        return Validator::make($data, [
            'name' => 'required|max:255',
            'email' => 'required|email|max:255|unique:users',
            'password' => 'required|confirmed|min:8|regex:/^(?=\S*[a-z])(?=\S*[A-Z])(?=\S*[\d])\S*$/',
        ], $messages);
    }

使用文档 http://php.net/manual/en/function.preg-match.php 和 Laravel 文档的正则表达式规则,我可以设置一个表达式来检查这些字符,我还可以设置一个自定义消息如果失败。

通过这些微小的工作我们可以用一个错误消息来帮助用户设置更好的密码。

925473f4a9_7cc829d3gw1f0bhka30krj20j60anjs8

技术雷达 : 关于技术趋势的分析报告

就在刚刚过去的2015年11月份,ThoughtWorks又发布了最新一版的技术雷达。技术雷达是什么,来源以及如何运用,可以参考Neal Ford的一篇文章《Build Your Own Technology Radar》中文翻译】,这里就不再赘述。在本期的技术雷达中,提出了四个最新的技术动态,分别为:“Docker引爆容器生态系统”、“微服务及相关工具受到追捧”、“JavaScript工具正在趋于平稳”、“安全是每一个人的问题”。本文就主要围绕这四个最新的技术动态,阐述一下笔者个人的理解和分析。

Docker引爆容器生态系统

Docker现在非常火,作为一个开源的应用容器引擎,它的出现让容器技术的使用和管理变得非常简单,也促使更多的人开始关注和意识到容器技术的真正价值和威力。由于其基于LXC的轻量级虚拟化技术,相比于KVM之类传统的虚拟机技术最明显的特点就是启动快,资源利用率高。启动一个容器只需要几秒钟,在一台普通的PC上甚至可以启动成百上千的容器,这都是传统虚拟机技术很难做到的。目前容器技术已经被广泛应用在软件开发的各个阶段各个领域,例如用于管理开发环境、用于测试、构建项目和实施持续集成,当然也可以作为传统云平台虚拟化的替代方案,实现更为轻量更具弹性的云计算平台。

虽然上文提到的这些应用场景都是非常有价值的,但还不能体现Docker或是说容器技术如此火爆的原因。我们知道Container通常翻译为容器,但是还有另一个翻译就是集装箱,集装箱被很多人称为是21世纪最伟大的发明之一,它的发明和广泛使用甚至改变了世界的货物运输体系,促进了经济的全球化发展,《集装箱改变世界》这本书就是讲述了集装箱是如何改变世界的。而我们现在所提的容器技术和Docker,是不是也在致力于改变软件的世界,改变我们开发、测试、构建、部署、运维所有这些的现有方式呢?我觉得是有可能的,因为无论是集装箱还是容器技术都为我们带来了两个重要的好处:一致性和隔离

E5B18FE5B995E5BFABE785A7-2015-12-05-E4B88BE58D889.27.22-1

我们知道一个产品是否可以正常提供服务,只去确保软件本身没有问题是远远不够的,需要同时保证软件、基础设施(例如硬件、操作系统和运行环境)以及配置的正确性和可靠性。而传统的软件开发方式,对于这三个方面的管理是分离的,再加上三者之间错综复杂的关系,就造成了我们常常挂在嘴边的“环境问题”。但是通过使用容器技术,我们如果将软件、基础设施和配置作为一个整体使用容器进行封装,产生一个个已经同时包含了软件以及其运行环境的经过严格测试检验的“包”。这样当部署“包”的时候就不需要再考虑环境的问题,也不需要关心现在部署的是一个Web服务还是一个数据库服务,要做的只是把一个个容器标准化地安装到指定的容器引擎即可。

E5B18FE5B995E5BFABE785A7-2015-12-05-E4B88BE58D889.26.07-1

可能正是大家都看到了容器技术以及Docker对于软件开发各个领域正在带来的改变,容器技术的生态系统也在经历着一个快速发展的阶段,涉及到开发辅助、集群管理、服务编排、内容发现、云平台搭建等各种工具框架都一一呈现在我们面前,其中像Google和Amazon这样的巨头也都在第一时间发布了各自与容器相关的服务和框架。

1224-E78E8BE581A5-3

微服务及相关工具受到追捧

如果大家关注Docker,也肯定会经常听到一种与之相关的架构,也就是微服务架构:

“微服务架构是一种架构模式,它提倡将单一应用程序划分成一组小的服务,服务之间互相协调、互相配合,为用户提供最终价值。每个服务运行在其独立的进程中,服务与服务间采用轻量级的通信机制互相沟通(通常是基于HTTP协议的RESTful API)。每个服务都围绕着具体业务进行构建,并且能够被独立的部署到生产环境、类生产环境等。另外,应当尽量避免统一的、集中式的服务管理机制,对具体的一个服务而言,应根据业务上下文,选择合适的语言、工具对其进行构建。”

这是Martin Fowler给出的对于微服务架构的定义,其中提到了微服务架构的四个特点:

  • 将单一的应用程序划分成一组小的服务
  • 每个服务运行在其独立的进程中
  • 轻量级的通信机制
  • 独立的部署到生产环境

我看过很多非常成功的公司在分享其系统架构演进历程时,往往最后都会落脚于服务拆分和业务服务化。其实这也不算是什么新的概念了,几年前流行的SOA面向服务架构就已经为我们描绘了一个服务化架构的美好前景。那为什么又提出了一种新的微服务架构呢?对于这个问题Martin Fowler在他的那篇《Microservices》也给出了他的回答。简要来说就是虽然这两种技术都是以服务化和组件化为目标,但是架构理念和技术策略上有太多的不同。例如上边提到的微服务架构的主要特点以及其倡导的演进式架构设计,去中心化的架构风格,采用轻量化通信机制,强调独立部署等都是与SOA所提倡的技术和思路有很大区别。微服务架构也更契合现代的技术发展趋势,例如RESTful API的流行,嵌入式应用服务器的应用,持续集成、持续交付的普及,容器技术爆发,组件化的趋势,云平台的发展等。

在引入微服务架构前,系统往往是以一个大的单体应用的形式存在的。此时任何功能的修改都需要重新构建部署整个应用,并且当需要水平扩展时也只能通过扩展整个应用的方式进行,无法做更细粒度的调度和控制。而当切换成微服务架构后,单一功能的修改只需要重新构建部署相应地服务即可,其他服务并不会受到影响。如果某个服务需要水平扩展时,我们也只需要扩展此服务即可。由此可见,微服务架构相比于传统的单体应用架构,可以极大的提高我们的资源利用效率和系统弹性。再加上通过服务化我们可以更容易的以组件的方式组合和重用现有服务,快速地构建出新的服务,使企业和产品更具竞争力。

1224-E78E8BE581A5-4

微服务架构还有很多其他的好处:例如我们可以为不同的服务使用异构的技术架构,用最适合的技术解决最适合的业务问题(例如在某些服务中使用关系型数据库,而在某些服务中使用NoSQL数据库);相对于单体应用因为每个服务都更小更简单,所以维护难度和成本也会比传统的大的单体应用要低得多;还有根据康威定律,这种新的服务架构甚至会改变我们软件开发的组织方式向小而精的多功能自组织团队和全栈式演进,前段、后端、运维、DBA这种角色划分方式也许也会因此而成为历史。

微服务架构之所以经常会和容器技术一起被提及,是因为容器技术为微服务架构提供了一个非常匹配的基础设施,从而可以将这种架构的威力最大化的激发出来。设想一下,假如我们有一个产品采用微服务架构,并将每类服务及其运行环境打包为容器,部署于像AWS ECS这类弹性容器服务里。就可以实现通过实时监控每类服务的负载情况,通过自动化的方式快速按需对每类服务基于容器技术进行快速高效的水平扩展或是撤销,这样我们的架构就是一个高度自动化、高弹性、高资源利用率的应用架构,相比于传统的单体应用也将具备很大的竞争优势。

有得必有失,微服务架构有着这么多的好处,但同样也会引入一些新问题,最直接的就是分布式本身所引入的复杂性。例如如何保证服务间的契约,如何快速开发服务,如何保证轻量级通讯协议的可靠性等等。对于这些问题也有着相对应的解决方案,本期雷达就推荐了很多的工具和技术来辅助进行微服务架构下的软件开发。

雷达 : 关于技术趋势的分析报告,首发于博客 – 伯乐在线