原文教材 与 参考资料:
Boneh Dan , Shoup Victor . A Graduate Course in Applied Cryptography[J].
该书项目地址(可以免费获取):http://toc.cryptobook.us/
博客为对该书的学习笔记,并非原创知识,帮助理解,整理思路。
18.0 引言
本章主要描述了身份认证协议,注意这里仅仅是描述参与者之间(客户端与服务器之间)如何进行身份的认证问题,暂时还不涉及密钥协商问题,为什么?因为任何的业务首先要做到的就是身份认证,只有确认了身份(单方面确认或者双方面确认)之后,才有协商会话密钥,更新会话密钥等一系列的其他操作,本节内容仅仅上是分析与描述身份证明与登录协议。
首先给出本章作为核心描述的三个问题,本章围绕这三个问题展开,并给出了相应的解决方案,我们以一张绘图来描述本章的框架结构:
关于身份协议的主要问题一共有三类:
1. 证明者与验证者 在物理上是十分接近的,敌手不具有窃听信道的功能,敌手只能以某种直接的方式假冒证明者,这种场景下,敌手的攻击行为被称为直接攻击。解决方案:口令协议 。
2. 证明者和验证者是通过无线信道进行认证的,敌手此时具备窃听信道的能力,此时使用使用简单的口令协议已经不在安全。解决方案:一次性口令协议。
3. 敌手可以构造虚假的验证者和证明者进行交互,从而获取证明者的信息,进一步伪装证明者身份与真正的验证者交互。解决方案:challenge-response.
需要注意的几点:
1. 验证密钥是可以公开的,公开验证密钥不会对系统造成破坏。
2.有状态的协议往往能够提供更高登记的安全与更低的开销,但是不容易使用,由于有状态的协议要求验证者和证明者需要某种程度上的同步。
3.单向验证只需要单方面验证身份,同时验证需要验证者和证明者同时验证对方的身份。
4.身份协议被设计用来保证在没有证明者协助的条件下,任何人不能扮演证明者的角色,但是无法建立起安全的通信会话,因为这个协议容易遭受到中间人攻击。
18.1 Interactive protocols: general notions
这里依旧给出一个交互式协议的图示:
交互式协议可以看成一个抽象的算法,输入为旧的配置与输入信息,输出为更新的配置与函数输出信息。
18.2 ID protocols: definitions
这里给出一个ID协议的形式化定义,非常简单,使用一贯的算法符号:
18.3 Password protocols: security against direct attacks
这里给出一个口令协议,思想非常简单,验证者预先存储了一个口令的哈希值,然后证明者发送哈希的原像给验证者,验证者本地计算哈希值后与自己存储的信息进行比对,如果相同则验证成功,这里需要注意的是,假设服务器可擦除自己计算的结果,如果不能及时的擦除计算哈希的信息,那么这个哈希将没有任何的积极作用,协议细节描述如下:
为了描述上述协议是安全的,我们构造一个攻击游戏刻画上述协议:
验证者扮演挑战者,敌手扮演证明者,敌手企图通过验证者的验证情况:
这个证明的记过是显而易见的,除非敌手能够攻破单向哈希函数的单向性,不然是无法攻破这个方案的,所以直接的得到下述安全性定理与证明:
18.3.1 Password cracking using a dictionary attack
口令协议非常容易被部署使用,但是作为人类来看,是不容易生成随机均匀的口令值的,并且口令值往往比较短,所以这些弱口令往往会被猜到。
敌手可以预先准备一些口令(可能是常见的使用频率高的),然后尝试使用准备好的口令去碰撞登录系统,那么由很高的概率是能够碰撞到一些使用弱口令的账户的。
这种攻击被称作字典攻击:字典攻击也有一些分类:
在线字典攻击:
对于一个使用弱密钥的账户,敌手可以使用字典持续的尝试登录,总有登录上的可能,一般系统可以采用登录失败增加等待时间的策略来进行抵御这类参与者。
线下字典攻击:
考虑这样一种情况,敌手可以用各种方法有效的盗用服务器上的哈希口令值,然后进行一个线下的比对,敌手可以简单采取以下的算法进行尝试,从而获得证明者身份,进而可以任意的模拟目标用户登录,计算复杂度为O(D)。
目前针对口令统计相关的研究较多,例如CrackStation等,理论上如果采用量子算法,那么该碰撞将会更容易被计算出来。
进一步,为了提高这个攻击速度,还可以预先计算一些口令的哈希值,然后直接进行哈希值是否相等的比较,该简单算法描述如下:
批量线下字典攻击(Batch offine dictionary attacks)
如果敌手能够获得某个服务器的登录口令文件,那么这个敌手可以运行一个字符串比较算法(例如KMP算法)以O( D + F )的复杂度完成比对。
18.4 Making dictionary attacks harder
如果能够使得敌手比较哈希值的复杂度提升,那么将能有效降低敌手的优势,一个有效的方式就是使用salts. 扩张口令空间,增加敌手的计算量,从而降低其优势,该算法的简单思想如下图所示:
不论是敌手进行预先计算哈希值 然后进行查找,或者是进行暴力猜测pw, salt都会增加敌手的计算量,下面将对敌手在有salt条件下的安全进行刻画,预计算部分被刻画为一个敌手的辅助字符串L,将敌手分为两个阶段,第一阶段敌手可以任意访问随机谕言机获取一个预先的字符串描述,然后再与挑战者交互进行安全挑战。
安全游戏刻画如上图所示并不难理解,另外这个定理18.2的证明,本章节没有,如果说需要查阅请找该书的参考文献【50】应当有较为完整的证明过程。这个安全定理给出了一个界限,描述了敌手只有进行暴力攻击才是最优解的界限,如果一个敌手选择一个弱密钥,那么还是很有可能导致信息泄露的。
还有一种方法就是采用一个秘密的salt, 要求服务器在每次计算过程中都必须进行一定次数的尝试,那么对于敌手而言,又线性的增加了计算量,该算法思想描述如下,
18.4.3 Slow hash functions
另外一种限制敌手的方法就是使用一类运行速度非常缓慢的哈希函数,那么敌手企图碰撞的计算时间将被提升,亦相当于给与增加了敌手的计算复杂度,例如,简单的迭代哈希算法计算量,进而达到降低敌手优势的目的,我们定义这种函数为password-based key deriavtion function, PBKDF。
一个被广泛使用在IOS 和 Windows的函数为:
18.4.4 Slow memory-hard hash functions
除了增加敌手计算哈希的时间外,我们可以进一步的增加敌手内存消耗,如果使得敌手必须使用更大的芯片 更大的内存,亦可以有效的降低敌手的优势。
一个有效的算法被称为Scrypt:
这个算法首先生成一个X向量,然后计算Y向量时必须访问之前的X向量,这要求计算机需要一直保存X向量不能释放该内存。如果想要高效计算这个算法就必须增加芯片上的内存空间,其中d就是控制内存大小的一个指示值,这个算法一般被封装在KDF中,如下所示,因为该算法可以有效提高运行内存的尺寸,并且如果需要降低运算速度,只需要迭代这个封装算法即可:
这里将芯片可以并行计算哈希函数的行为建模为一个并行随机谕言机,并在依据本书的参考文献【4】给出一下的定理,证明了敌手即使能够使用并行的芯片计算哈希函数,内存复杂度依然需要 。