第二十一章学习笔记

存储秘密

怎样存储像口令和密钥这样的长期秘密呢?要满足两个相反的要求。首先,这个秘密应该保持其私密性;其次,丢失这个秘密(也就是再也找不到这个秘密)的风险应该尽可能小.

(1)磁盘

存储秘密的一个很直接的办法是把秘密存储在计算机的硬盘上或其他永久存储介质上,这是可行的,但只在计算机本身确保安全的情况下。如果 Alice在她的电脑上(未经加密地)存储她的密钥。那么任何使用她电脑的人都能使用她的密钥。大多数电脑都会被别人使用,至少偶尔会被别人使用。Alice不会介意别人用她的电脑,但同时,她也不想让别人顺便访问自己的银行账户。另一个问题是,Alice可能会使用不止一台计算机。如果她的密钥存储在家里的计算机上,那么她工作或旅行时就不能使用密钥。Alice 到底应该把密钥存在家里的台式计算机里还是她的便携式计算机里呢?我们并不希望看到她把密钥复制到多个地方,那样显然会进一步削弱系统的安全性。
一个更好的解决方案是让 Alice把密钥存储在她的PDA或智能手机上。这些设备很少会借给别人使用,而且无论去哪里都会随身携带。但这些小型设备很容易丢失或失窃,而我们不希望后来获得这部手机的人能访向密钥。
我们需要用主密钥来加密密钥,而主密钥需要被存储在某处。把它存储在被加密的密钥旁边不会给系统带来任何优势。但这是减少秘密信息的大小和数目的有效技术,它被与其他技术结合起来广泛使用。例如,RSA的私钥有几千位长,但通过用对称密钥对它加密和认证,可以以可观的量级将所需的安全存储空间减小。

(2)人脑记忆

一个想法是把密钥存储在 Alice 的大脑中。我们让她记住一个口令,并且用这个口令加密所有其他密钥。被加密的密钥可以存储在任何地方,也许在磁盘上,但也可能在 Web服务器上,Alice能把它下载到任何她正在使用的计算机上。
人类记忆口令的能力是相当差的。如果选择很简单的口令,又不能得到任何安全保障。实际上,根本不存在足够简单又相当安全的口令∶攻击者仅仅通过穷举攻击就能够破获。使用你妈妈婚前名字也不安全,她的名字通常是公开的,即便没有公开,可能只存在几十万个姓氏,攻击者可以通过尝试找到正确的那一个。
密码短语无疑是人脑中存储秘密的最好方法。遗憾的是,很多用户对正确地使用该方法仍然慰 仍然感到很困难。即便是用密码短语,在人脑中储存128 位的熵也是相当难的。

加盐和扩展
为了从有限熵的口令或密码短语中产生最大的安全性,我们可以使用两种技术。这两种技术的名字听起来像是来自中世纪的酷刑室。这些技术是如此的简单和明显,以至于可以应用在所有口令系统中,实在没有任何理由不使用它们。
首先是加盐(salt)。盐就是一个随机数,与加密的口令存放在一起。最好采用256 位的盐。
下一步是扩展(stretch)口令。扩展一定是很长的计算。令p是密码口令,s是盐。使用image任意保密性强(eryptographically strong)的散列函数h,计算∶image
用K作为密钥来实际加密数据。参数r是计算迭代的次数,只要实际情况允许,r值应该尽可能大。(这里没有说x,和 K应该达到 256 位长。)现在,从攻击者的角度来看看这个问题。给定盐s和用K加密的数据,你试图通过尝试不同的口令来找到K。选择一个特定的密码口令p,计算相应的K,用它解密数据,检查解密结果是否有意义并且能通过相关的完整性检查。如果不是,则p必定是假的。为了检查单个的p,必须要做r次不同的散列计算。r越大,攻击者做的工作就越多。在解密数据之前就检查出密钥是否正确,这在有些情况下可能会比较有用。这里,需要一个密钥检查值来进行检查。例如,密钥检查值可以是力(x,-Ilpls),因为散列函数的性质独立于密钥K。这个密钥检查值可以和盐值一起存储,用于在用K解密消息前检查口令是否正确。在正常使用中,每次用到口令时都要进行扩展计算。但是记住,扩展计算是在用户刚键入口令时完成的。键入口令可能要用几秒钟,因此用200 毫秒来进行口令处理是可以接受的。我们可以按照这样的规则选择r;r值使在用户设备上根据(s,p)计算K大约花费200 ~1000毫秒。随着计算机的发展,其计算能力不断增强、速度加快,因此r也应随之不断增大。理想地说,当用户第一次设置口令时要通过实验来决定r,然后把r和s存放在一起(要保证 r是一个合理的值,不太大也不太小)。

当攻击者同时攻击大量口令时。盐能够防止他利用规模扩大而节约计算量。假定系统中有100万个用户,每个用户存储一个包含他的密钥的加密文件,每个文件是由用户的扩展口令来加密的。如果我们不使用盐,那么攻击者就可以进行如下的攻击∶猜测密码口令p,计算扩展密钥K,试图用K解密每个密钥文件。对于每个口令来说,扩展函数仅仅需要计算一次,最终的扩展密钥可以被用于尝试解密每个文件

(3)便携式存储

存储秘密的另一个办法是在计算机之外存储。最简单的存储方式是把口令写在一页纸上。大多数人使用这种办法,甚至对于像网站这样的非密码系统也如此。很多用户至少有半打的口令要记住,实在太多了,尤其是某些系统很少使用口令因此为了记住口令,用户就把它们写下来。这种解决方案的局限性在于,每次使用口令时仍然需要通过用户的眼睛、大脑和手指来处理。为了把用户的错误限制在一个合理的界限内、这种技术仅仅适用嫡比较低的口令和密码短语。
作为设计者,不必为这种方法进行设计和实现。无论怎样制定规则、怎样创建口令系统,用户都会这样来存储口令。
一个更先进的存储方法是便携式存储。它可以是一张存储芯片卡、一张磁条卡、一个USB 盘或是任何其他种类的数字存储设备。数字存储系统总是能存储至少256位的密钥,因此我们可以排除低熵的口令。便携式存储变得非常像一个密钥,无论谁得到它,都能够拥有访问权,因此需要安全地放置

(4)安全令牌

一个更好但也更贵的解决方案是使用我们称为安全令牌的设备。这是 Alice能够随身携带的一个小型计算机。令牌的外部形状可以千变万化,从智能卡(看起像信用卡)到iButton、USB 加密狗(USB dongle)或PC卡。它的主要性质是有一个永久性存储器(例如,没电时仍能保存数据的内存)和一个 CPU.
安全令牌主要作为一个便携式存储设备来工作,但它在安全性上又有几点改进。首先,通过口令或类似的方法来限制访问被存储的秘密。在安全令牌让你使用密钥之前。一定要给它一个正确的口令。如果输入了三五次错误的口令,安全令牌就不允许用户访问了,通过这种方式可以防止攻击者对口令进行穷举搜索。当然,某些用户会过于频繁地输错口令,于是他们的安全令牌就不得不恢复(resuscitated)。但你可以用更长、熵值更高的密码短语或密钥来保证恢复过程的安全.
安全令牌目前是最好也最实用的存储密钥的方法之一。它们相对便宜,并且足够小,方便携带。
用户行为是实际使用中需要注意的一个问题。当用户去吃饭或者开会时,他们会把插在计算机上的安全令牌留在那里。由于用户不想每隔很短的时间间隔就重新输入口令,因此系统会被设置成在最后一次被键入口令后的几小时内允许访向,于是攻击者要做的一切就是走过去并使用存储在安全令牌中的密钥。

(5)安全 UI

安全令牌仍然存在显著的缺陷。Alice 不得不在PC或其他设备上输入她使用的口令。只要我们信任 PC.这就不是问题,但我们知道 PC都不是很安全。事实上,不把Alice的密钥存在 PC中的主要原因就是不太信任它。如果令牌本身有一个安全的内置 UI,我们就能得到更多的安全性。考虑一个有内置键盘和显示屏的安全令牌,那么口令或PIN就能够直接输入令牌而不需要信任外部的设备了。
把键盘嵌在令牌中能防止 PIN 被攻破。一旦PIN 被键入,PC 仍然会得到密钥,那么它就能用这个密钥做任何事情,因此我们仍然被整个 PC 的安全性所限制。
为了阻止密钥的泄露,我们必须把涉及密钥的密码学过程嵌入令牌,这就要求在令牌中有应用专用(application-specific)的代码。这个令牌很快就会发展成一台全功能计算机,不过是一台用户能随身携带的可信任的计算机。这个可信任的计算机能在令牌中实现每个应用的关键安全部分。显示功能现在变得很关键,因为显示功能会告诉用户他正在通过键入PIN授权什么行为。在一个典型的设计中,用户使用PC的键盘和鼠标来进行操作。例如,当银行支付被授权时,PC把数据发送给令牌。令牌显示数量和其他的一些交易细节,用户通过敲击他的 PIN 来授权交易,然后令牌签署交易细节,PC 完成交易的其余部分。

(6)生物识别技术

果我们想做得更漂亮些,还可以结合一些生物识别技术。你可以把类似指纹扫描仪或虹膜扫描仪的设备嵌入安全令牌中。但目前生物设备并不是很有用。指纹扫描仪可以以合理成本生产。但所提供的安全性整体不太好。2002年,密码学家Tsutomu Matsumoto和他的3个学生演示了它能稳定地骗过市面上能买到的所有商用指纹扫描仪,而且仅仅采用了很普通的材料同。即是从潜在的指纹(例如,你留在每个光滑表面上的指纹)中伪造一个假指纹,也不过是一个聪明中学生的兴趣爱好项目的难度。
虽然指纹扫描仪很容易被欺骗,但仍然很有用。假定你有一个安全令牌,它带有一个小显示器、一个小键盘和一个指纹扫描仪。为了得到密钥,你需要对令牌进行物理控制,得到PIN,伪造指纹。与以前的解决方案相比,攻击者需要做更多的工作。它可能是目前我们所能达到的最实用的密钥存储方案。另一个方面,安全令牌是相当昂贵的,因此它不能被很多人使用。
指纹扫描仪也可以被应用在安全性要求不高的方案中。用手指触摸扫描仪可以快速完成,让用户经常这样做也是可行的。指纹扫描仪可以提高「适当的人正在授权计算机做某事」的可信度。这增加了雇员把口令借给同事的难度。指纹扫描仪不能防范很高级的攻击者,它可以用来防止安全制度的临时破坏。与把扫描仪用作高安全性的设备相比,这对安全性来说也许是一个更重要的贡献。

(7)单点登录

般的用户都有很多口令,因此产生一个单点登录系统就变得很有吸引力。办法是给Alice一个的主口令,然后用它来给不同应用中的不同口令加密。为此,所有的应用都必须与单点登录系统对话。无论何时,只要应用需要口令,都不应该询问用户,而是由单点登录程序来完成。如果要让这个系统大规模工作,会遇到无数挑战。让我们想想这种情形吧∶所有的应用都要被修改,以便能够自动从单点登录系统中取得口令。
更简单的办法是用一个小程序把口令都存在一个文本文件中。Alice键人她的主口令,然后用复制和粘贴功能把口令从单点登录程序复制到应用中。Bruce设计了一个叫作Password Safe的免费程序来完成这一操作,但这仅仅是 Alice把她的密码写在一张纸上的加不是最终的解决方案。

(8)丢失的风险

一个密钥存储系统既容易使用又高度可靠是很难的。因此一个好的经验法则是,把这些功能分开。保持密钥的两个副本∶ 一个容易使用,另一个更可靠。如果容易使用的系统忘记了密钥,可以从可靠存储的系统中恢复它。找到可靠的系统很简单,写在银行地下室的一页纸上怎么样呢?
当然,一定要注意保护可靠存储系统。通过设计,它很快会用于存储所有密钥,那么这就很容易成为攻击者的目标。应该做一个风险分析以决定是用一系列小的可靠系统存储密钥好,还是用单个的大的系统更好。

(9)秘密共享

你需要更安全地来存储某些密钥,例如,CA中私有的根密钥。我们已经看到,以安全的方式存储秘密是很困难的,安全且可靠地存储它就更困难了。
有一种密码学解决方案能够帮助我们存储密钥,它叫作秘密共享(secret sharing)。这有些用词不当,因为它暗示着你要同几个人共享秘密。实际上不是这样的,该方法是把这个秘密分成几个不同的分块(share)。它可能以这样的方式来处理,例如,用5个分块中的3个就可以恢复秘密。那么你可以把分块分给IT部门的每个高级成员,他们中的任何3个人都能恢复秘密。这种方式的技巧就是任意两个人在一起绝对不会知道关于密钥的任何事情。
在现实生活中,秘密共享方案很少被使用,因为它们太复杂了。它们不但应用起来复杂,更重要的是,管理和操作也很复杂。大多数公司没有一群很负责的彼此信任的人。你可以尝试去告诉某个部门的成员,就说会给他们每人配备一个带有密钥分块的安全令牌,并且他们要在星期日早晨3点的紧急情况中露面。是的,他们彼此之间并不信任,但却要保持自己的分块安全,不被其他成员盗用。每次当某人加入或离开部门时,他们也需要去安全密钥管理房间以得到一个新的密钥分块。实际上,这意味着在部门成员出差的情况下也要这样。CEO 持有分块也不是很有用的,因为CEO 更容易出差。在你知道出差之前,要把它交给两个或三个高级 IT 管理人员。他们能够使用秘密共享方案,但代价和复杂性已经使它没有吸引力了。为什么不使用更简单的方案呢?例如,像银行地下室这样的物理解决方案。它有几个优势∶每个人都理解它是怎样工作的,因此不需要特殊的培训。他们已经被测试过了,而秘密重构过程是很难测试的,因为它需要大量的用户交互行为,你一定不想在秘密重构的过程中出现 bug,那会导致你失去 CA 的根密钥。

(10)清除秘密

要清除写在纸上的口令一般是把这张纸销毁。一种可能的方法是烧掉这张纸,然后把灰烬碾成粉末,或者是用水把灰烬混成纸浆。把纸切成碎片也是一种选择。虽然很多碎纸机切成的碎片很大,这就使得把纸重新合成起来更容易一些。

磁存储介质

磁介质是很难清除的。讨论这项清除技术的文献意外的少,我们所知道的最好的一篇文章是 Peter Gutmann写的,虽然其中的一些技术细节现在可能已经过时了。
磁介质在小型磁区域中存储数据,区域的磁化方向决定了它编码的数据。当数据被重写时,磁化方向也被转变以反映新的数据。但是有几个机制能防止旧的数据完全丢失。用来重写旧数据的读/写头从来就没有被准确定位,它会留下一些旧的数据。重写并不能完全清除旧的数据。你可以把它想象成用单层涂料来重新刷墙,你仍然会模糊地看到下面的旧涂料。
磁化区也会移至读写头控制的磁道外或深层磁化材料中,在那里数据可存放很长时间。用一般的读/写头来重写数据是不能恢复的,但拆开磁盘驱动器并使用特殊装置的攻击者也许会恢复部分或所有的旧数据。
实际上,用随机数据重复地重写秘密可能是一个最好的办法。这里要记住以下几点∶

  • 每次重写应该使用新的随机数据。一些研究工作者已经开发了特定的数据模式、这些模式被认为能更好地清除旧数据。但模式的选择还要由磁盘驱动器的具体细节来决定。随机数据也许会要求对同一结果进行更多次的重写。但它在所有情况下都有效,因此更安全。
  • 定要在存储秘密的实际位置重写。如果仅仅通过给文件写入新数据来改变它,文件系统也许会决定在不同的位置存储新数据,这会保留原始数据。
  • 要保证每次重写是写到磁盘上,而不是写到磁盘缓存中。这种写缓存的磁盘驱动器存在一定的危险,因为它们也许会缓存新数据,并把多个重写操作优化为一个。
  • 个可能比较好的方法是清除自秘密数据之前开始,且到它之后结束一段区域,因为磁盘驱动器的旋转速度从来都不完全一致,新的数据并不能准确对准旧的数据。

就我们所知,没有一个可靠的信息能说明需要进行多少次重写操作,但我们没有理由选择较少的次数。要清除的仅仅是单个密钥(如果你有很多秘密数据。用这个密钥加密那些数据,仅仅清除密钥即可)。我们认为用随机数据进行50次或100次重写是完全合理的。
使用消磁机来清除磁带或磁盘从理论上说是可行的。然而,现代的高密度磁盘存储介质能够抵抗消磁,因此这不是一个可靠的清除方法,实际上,用户根本弄不到消磁机,因此这也是不现实的。
甚至对于扩展了的重写都会有很专业的、资金充足的攻击者从磁介质中把秘密恢复出来。为了完全地清除数据,可能不得不清除介质本身。如果磁化层是塑料的(软盘或磁带),可以把它切碎,然后烧掉。对于硬盘,可以用磨光机把磁化层从盘中取出,或是用喷灯把磁盘熔化成液体。实际上,你并不想让用户采取这么极端的措施,因此反复重写是最实际的解决方案。

固态存储

清除像 EPROM、EEPROM 和闪存这样的非易失性内存也会有同样的问题。对旧数据进行重写不能根本地清除旧数据,我们之前讨论的数据保留机制也会起作用。而且,用随机数据重复地重写秘密是仅有的一种实际解决方案,但也不是很完美的方案。因此只要不再需要某种固态设备了,就应该销毁它。

posted @ 2021-05-15 20:48  Li_Ang  阅读(57)  评论(0编辑  收藏  举报