购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

1.5 软件架构安全

设计架构时要考虑的一个重要因素是安全性方面的需求。并非所有应用程序情况都一样,所以有些应用程序在这方面的需求可能比其他应用程序宽松一些。例如,与讨论猫的网络论坛相比,银行应用程序的安全性需求要高不止100倍。这方面最常见的例子是密码的存储问题。最幼稚的方法是将密码以纯文本形式保存,且与用户名或电子邮件地址相关联——例如,存储在一个文件或一个数据库的表中。当用户尝试登录时,系统接收输入的密码,并将其与之前存储的密码进行比较,如果它们是相同的,就允许用户登录,对吧?

事实上,这是一种非常糟糕的方法,因为它可能产生严重的问题:

❍如果攻击者能够访问应用程序的存储空间,他们就能读取所有用户的密码。用户通常会重复使用密码(尽管这是一个不好的习惯),因此,只需将密码与他们的电子邮件地址进行匹配,用户将面临多个应用程序的攻击,而不仅是被突破的那个。

这种情况似乎不太可能发生,但请记住,任何存储的数据副本都面临着攻击的威胁,包括备份数据在内。

❍另一个现实问题是来自内部的威胁,即那些可能有合法权限进入系统,但出于恶意目的或误操作而复制了数据的工作人员。对于非常敏感的数据,这应该当作一个非常重要的考虑因素。

❍诸如在状态日志中将用户密码显示出来这样的错误。

为了保障系统的安全,数据的存放应当在不暴露用户的真实密码的情况下进行,尽可能地保护其不被访问和复制。对此,通常的解决方案如下:

1.不存储密码本身。取而代之的是存储密码加密之后的 散列值 (hash,亦称哈希值)。这个过程是采用数学函数对密码明文进行运算,产生一个可复制的比特序列,但其逆向操作在计算上是非常困难的。

2.由于散列值是基于输入的信息,其结果是确定的,因此恶意攻击者可以检测到重复的密码,因为针对同样的密码明文,它们的散列值也会相同。为了避免这个问题,可以为每个账户添加一个随机的字符序列,称之为 (salt)。在散列运算之前盐会被添加到每个密码中,这意味着两个拥有相同密码但盐值不同的用户将拥有不同的散列值。

3.生成的密码散列值和盐值都被存储起来。

4.当用户尝试登录时,他们输入的密码被添加到盐中,然后将其散列运算结果与存储的散列值进行比较。如果是正确的,则允许用户登录。

注意,在这个设计中,实际的密码对系统来说是未知的。它并没有被存储在任何地方,只是在经过处理之后临时被接受,用来与预期的散列值进行比较。

这个例子是以一种简化的方式呈现的。有多种方法可以使用这个模式,并且可以采取不同的方式来比较散列值。例如,bcrypt函数可以应用多次,每次都强化密码,这样会增加生成有效散列值的时间,从而使其能更有效地防御暴力破解攻击。

这种系统比直接存储密码的系统更安全,因为操作该系统的人也不知道密码,同时也不会把密码存储在系统中的任何地方。

错误地在状态日志中显示用户密码的问题仍然可能发生!应该格外小心,以确保敏感信息不会因失误而被记录下来。

在某些情况下,可以采取与密码保护相同的方法对其他存储的数据进行加密,这样只有客户可以访问自己的数据。例如,我们可以为某个信道启用端到端的加密功能。

安全性与系统的架构有着非常密切的关系。正如我们之前看到的,架构决定了哪些方面容易调整,哪些方面难以改变,可以使一些不安全的操作无法进行,比如我们在前面的例子中讨论的关于用户密码的问题。其他做法还包括不存储来自用户的数据以保护其隐私,或者减少内部API中发布出来的数据等。软件安全是一个非常困难的问题,而且往往是一把双刃剑,为了让系统更加安全,可能会产生使操作变得烦琐和不方便的副作用。 wh4EnwczAWNkCXEIxZq+PkP5uxsi6Q/y6xHylhF9dqpr/lrEkJkVP9QFWgkDXDxh

点击中间区域
呼出菜单
上一章
目录
下一章
×