网络安全之身份认证
2020-10-12 09:55:02 阿炯

下文转自微信公众号:计算机与网络安全(ID:Computer-network)

原始出处已不可考,感谢原作者。

在网络环境下的信息世界,身份是区别于其他个体的一种标识。为了与其他个体有所区别,身份必须具有唯一性。当然,唯一性也是有范围的,如电话号码,在一个区域内是唯一的,如果考虑多个区域,可能会有相同的号码,但只要再添加区域号段,又能唯一区分开来。网络环境下的身份不仅仅用于标识一个人,也可以用于标识一个机器、一个物体,甚至一个虚拟的东西(如进程、会话过程等)。因此,网络环境下的身份是只在一定范围内用于标识事、物、人的字符串。

一、身份认证概述

网络环境下的认证不是对某个事物的资质审查,而是对事物真实性的确认。结合起来考虑,身份认证就是要确认通信过程中另一端的个体是谁(人、物、虚拟过程)。

那么,怎么知道通信的另一端是谁呢?通常,通信协议都要求通信者把身份信息传输过来,但这种身份信息仅用于识别,不能保证该信息是真实的,因为这个身份信息在传输过程中是可以被恶意篡改的。那么,怎样才能防止身份信息在传输过程中被恶意篡改呢?事实上要完全杜绝恶意篡改是不可能的,特别是在公共网络(如互联网)上传输的信息,而能做的,就是在身份信息被恶意篡改后,接收端可以很容易检测出来。

要识别真伪,首先要“认识”真实的身份。通过网络传递的身份可能是陌生人的身份,如何判断真伪?这里需要阐述一个观点:要识别真伪,必须先有信任。在网络环境下,信任不是对一个人的可靠性认可,而是表明已经掌握了被验证身份者的重要秘密信息,如密钥信息。假设A与B之间有一个得到确信的共享密钥,不管这个共享密钥是怎么建立的,他们之间就建立了相互信任。如果A确信掌握B的公开密钥,也可以说A对B建立了信任,但还不能说明B对A建立了信任。从上述讨论不难看到,在完全没有信任基础的情况下,新的信任是不能通过网络建立的,否则是不可靠的。

二、身份认证机制

身份认证的目的是鉴别通信中另一端的真实身份,防止伪造和假冒等情况发生。进行身份认证的技术方法主要是密码学方法,包括使用对称加密算法、公开密钥密码算法、数字签名算法等。

对称加密算法是根据Shannon理论建立的一种变换过程,该过程将一个密钥和一个数据充分混淆和置乱,使非法用户在不知密钥的情况下无法获得原始数据信息。当然一个加密算法几乎总伴随着一个对应的解密算法,并在对称密钥的参与下执行。典型的对称加密算法包括DES和AES。

公钥密码算法需要2个密钥和2个算法:一个是公开密钥,用于对消息的加密;一个是私钥(私有密钥),用于对加密消息的解密。根据名称可以理解,公开密钥是一个能公开的密钥,而私钥只能由合法用户掌握。典型的公钥密码算法包括RSA公钥密码算法和数字签名标准DSS。

数字签名实际是公钥密码的一种应用,其工作原理是,用户使用自己的私钥对某个消息进行签名,验证者使用签名者的公开密钥进行验证,这样就实现了只有拥有合法私钥的人才能产生数字签名(不可伪造性)和得到用户公钥的公众才可以进行验证(可验证性)的功能。

根据身份认证的对象不同,认证手段也不同,但针对每种身份的认证都有很多种不同的方法。如果被认证的对象是人,则有三类信息可以用于认证:
(1)你所知道的(what you know),这类信息通常理解为口令;
(2)你所拥有的(what you have),这类信息包括密码本、密码卡、动态密码生产器、U盾等;
(3)你自身带来的(what you are),这类信息包括指纹、虹膜、笔迹、语音特征等。

一般情况下,对人的认证只需要一种类型的信息即可,如口令(常用于登录网站)、指纹(常用语登录电脑和门禁设备)、U盾(常用于网络金融业务),而用户的身份信息就是该用户的账户名。在一些特殊应用领域,如涉及资金交易时,认证还可能通过更多方法,如使用口令的同时也使用U盾,这类认证称为多因子认证。

如果被认证的对象是一般的设备,则通常使用“挑战—应答”机制,即认证者发起一个挑战,被认证者进行应答,认证者对应答进行检验,如果符合要求,则通过认证;否则拒绝。移动通信系统中的认证就是一个典型的对设备的认证,这里设备标识是电话卡(SIM卡或USIM卡),认证过程则根据不同的网络有不同的方法,例如,GSM网络和3G网络就有很大区别,LTE网络又与前2种网络有很大不同,但都使用了“挑战—应答”机制。

在物联网应用环境下,一些感知终端节点的资源有限,包括计算资源、存储资源和通信资源,实现“挑战—应答”机制可能需要付出很大代价,这种情况下需要轻量级认证。为了区分对人的认证和对设备的认证,把这种轻量级认证称为对物的认证。其实,对物的认证不是很严格的说法,因为在具体技术上是对数据来源的认证。

三、对“人”的认证

人在网络上进行一些活动时通常需要登录到某个业务平台,这时需要进行身份认证。身份认证主要通过下面3种基本途径之一或其组合来实现:所知(what you know),个人所知道的或掌握的知识,如口令;所有(what you have),个人所拥有的东西,如身份证、护照、信用卡、钥匙或证书等;个人特征(what you are),个人所具有的生物特性,如指纹、掌纹、声纹、脸形、DNA、视网膜等。

(一)基于口令的认证

基于口令的认证方式是较常用的一种技术。在最初阶段,用户首先在系统中注册自己的用户名和登录口令。系统将用户名和口令存储在内部数据库中,注意这个口令一般是长期有效的,因此也称为静态口令。当进行登录时,用户系统产生一个类似于时间戳的东西,把这个时间戳使用口令和固定的密码算法进行加密,连同用户名一同发送给业务平台,业务平台根据用户名查找用户口令进行解密,如果平台能恢复或接收到那个被加密的时间戳,则对解密结果进行比对,从而判断认证是否通过;如果业务平台不能获知被加密的时间戳,则解密后根据一定规则(如时间戳是否在有效范围内)判断认证是否通过。静态口令的应用案例随处可见,如本地登录Windows系统、网上博客、即时通信软件等。

基于静态口令的身份认证技术因其简单和低成本而得到了广泛的使用。但这种方式存在严重的安全问题,安全性仅依赖于口令,口令一旦泄露,用户就可能被假冒。简单的口令很容易遭受到字典攻击、穷举攻击甚至暴力计算破解。特别地,一些业务平台没有正确实现使用口令的认证流程,让用户口令在公开网络上进行传输,认证方收到口令后,将其与系统中存储的用户口令进行比较,以确认对象是否为合法访问者。这种实现方式存在许多隐患,一旦记录用户信息的文件泄露,整个系统的用户账户信息连同对应的口令将完全泄露。网上发生的一系列网络用户信息被公开到网上的现象,反映的就是这种实现方式的弊病。另外,这种不科学的实现方式也存在口令在传输过程中被截获的安全隐患。随着网络应用的深入化和网络攻击手段的多样化,口令认证技术也不断发生变化,产生了各种各样的新技术。为了防止一些计算机进程模拟人自动登录,许多业务平台还增加了计算机难以识别的模糊图形。

基于口令的身份认证容易遭受如下安全攻击。

(1)字典攻击。攻击者可以把所有用户可能选取的密码列举出来生成一个文件,这样的文件被称为“字典”。当攻击者得到与密码有关的可验证信息后,就可以结合字典进行一系列的运算,来猜测用户可能的密码,并利用得到的信息来验证猜测的正确性。
(2)暴力破解。也称为“蛮力破解”或“穷举攻击”,是一种特殊的字典攻击。在暴力破解中所使用的字典是字符串的全集,对可能存在的所有组合进行猜测,直到得到正确的信息为止。
(3)键盘监听。按键记录软件以木马方式植入到用户的计算机后,可以偷偷地记录下用户的每次按键动作,从而窃取用户输入的口令,并按预定的计划把收集到的信息通过电子邮件等方式发送出去。
(4)搭线窃听。通过嗅探网络、窃听网络通信数据来获取口令。目前,常见的Telnet、FTP、HTTP 等多种网络通信协议均用明文来传输口令,这意味着在客户端和服务器端之间传输的所有信息(包括明文密码和用户数据)都有可能被窃取。
(5)窥探。攻击者利用与用户接近的机会,安装监视设备或亲自窥探合法用户输入的账户和密码。窥探还包括在用户计算机中植入木马。
(6)社会工程学(Social Engineering)。这是一种通过对受害者心理弱点、本能反应、好奇心、信任、贪婪等设置心理陷阱进行诸如欺骗、伤害等手段,取得秘密信息的手法。
(7)垃圾搜索。攻击者通过搜索被攻击者的废弃物(如硬盘、U 盘、光盘等),得到与口令有关的信息。

为了尽量保证安全,在使用口令时通常需要注意以下几点:
(1)使用足够长的口令,不使用默认口令;
(2)不要使用结构简单的字母或数字,尽量增加密码的组合复杂度;
(3)避免在不同平台使用相同的口令,并且要定期更换口令。

为克服静态口令带来的种种安全隐患,动态口令认证逐渐成为口令认证的主流技术。顾名思义,动态口令是指用户每次登录系统的口令都不一样,每个口令只使用一次,因而也叫一次性口令(OTP , One Time Password),具有“一次一密”的特点,有效保证了用户身份的安全性。但是如果客户端与服务器端的时间或次数不能保持良好的同步,就可能发生无法使用的问题。OTP的原理是采用一类专门的算法(如单向散列函数变化)对用户口令和不确定性因子(如随机数)进行转换生成一个一次性口令,用户将一次性口令连同认证数据提交给服务器。服务器接收到请求后,利用同样的算法计算出结果与用户提交的数据对比,对比一致则通过认证;否则认证失败。通过这种方式,用户每次提交的口令都不一样,即使攻击者能够窃听网络并窃取登录信息,但由于攻击每次窃取的数据都只有一次有效,并且无法通过一次性口令反推出用户的口令,从而极大地提升了认证过程的安全性。 OTP 从技术上可以分为3种形式:“挑战—应答”、时间同步和事件同步。


图1 动态口令的3种方式

(1)“挑战—应答”。“挑战—应答”认证机制中,通常用户携带一个相应的“挑战—应答”令牌,如图1(a)所示。令牌内置种子密钥和加密算法。用户在访问系统时,服务器随机生成一个挑战并将挑战数发送给用户,用户将收到的挑战数手工输入到“挑战—应答”令牌中,“挑战—应答”令牌利用内置的种子密钥和加密算法计算出相应的应答数,将应答数上传给服务器,服务器根据存储的种子密钥副本和加密算法计算出相应的验证数,和用户上传的应答数进行比较来实施认证。不过,这种方式需要用户输入挑战数,容易造成输入失误,操作过程较为繁琐。近年来,通过手机短信实现OTP验证码用得比较广泛。是目前主流的OTP验证方式,目前被广泛用于交易系统以及安全要求较高的管理系统中。

(2)时间同步。原理是基于动态令牌和动态口令验证服务器的时间比对,如图1(b)所示,基于时间同步的令牌,一般每60 s产生一个新口令,要求服务器能够十分精确地保持正确的时钟,同时对其令牌的晶振频率有严格的要求,这种技术对应的终端是硬件令牌。目前,大多数银行登录系统采用这种动态令牌登录的方式,用户持有一个硬件动态令牌,登录到系统时需要输入当前的动态口令以便后台实现验证。近年来,基于智能手机的软件动态令牌逐渐受到青睐,用户通过在智能手机上安装专门的客户端软件并由该软件产生动态口令完成登录、交易支付过程。例如,“支付宝”APP便是一款携带动态令牌的手机客户端软件。

(3)事件同步。事件同步机制的动态口令原理是通过特定事件次序及相同的种子值作为输入,通过特定算法运算出相同的口令。事件动态口令是让用户的的密码按照使用的次数不断动态地发生变化。每次用户登录时(当作一个事件),用户按下事件同步令牌上的按键产生一个口令,与此同时系统也根据登录事件产生一个口令,两者一致则通过验证。与时钟同步的动态令牌不同的是,事件同步令牌不需要精准的时间同步,而是依靠登录事件保持与服务器的同步。因此,相比时间同步令牌,事件同步令牌适用于非常恶劣的环境中,即便是掉进水中也不会发生失步问题,图1(c)是一个事件同步令牌的实例产品。

基于口令认证是目前使用最为广泛的身份认证技术,静态口令认证主要用于系统登录时的身份验证如门户网站、网上银行的登录。而在银行支付、网上银行转账、交易时一般采用静态口令+动态口令组合的方式进行认证。例如,在支付宝中交易时,支付宝系统要求用户同时输入支付口令及与该账户绑定的软件动态令牌。招商银行在进行低额度交易、转账时采用静态口令与短信动态验证码,这种双重保障的方式可以大大提高使用的安全性。

(二)双因子身份认证技术

在一些对安全要求更高的应用环境,简单地使用口令认证是不够的,还需要使用其他硬件来完成,如U盾、网银交易就使用这种方式。在使用硬件加密和认证的应用中,通常使用双因子认证,即口令认证与硬件认证相结合来完成对用户的认证,其中,硬件部分被认为是用户所拥有的物品。使用硬件设备进行认证的好处是,无论用户使用的计算机设备是否存在木马病毒,都不会感染这些硬件设备,从而在这些硬件设备内部完成的认证流程不受木马病毒的影响,从而可提高安全性。但另一方面,这些额外的硬件设备容易丢失,因此,需要双因子认证;也容易损坏,因此在增加成本的同时,也带来更多不便利。

实际应用中,每个用户均拥有一个仅为本人所有的唯一私钥,用于进行解密和签名操作,同时还拥有与接收方相应的公钥用于文件发送时进行加密操作。当发送一份保密文件时,发送方使用接收方的公钥对该文件内容进行加密,而接收方则能够使用自己所有的相应私钥对该文件进行解密,从而保证所发送文件能够安全无误地到达目的地,并且,即使被第三方截获,由于没有相应的私钥,该第三方也无法对所截获的内容进行解密。

使用U盾前,一般都要先在客户端PC上安装相应的驱动程序,使U盾能正常工作,同时还需安装数字证书认证身份。当用户需要交易,如向银行提交支付订单时,就需对用户的身份进行验证,此时系统会提示用户插入U盾,并输入U盾密码,系统会在后台对U盾提交的信息进行验证,用户看不到具体的验证过程,但验证一经通过,用户就可以继续后续操作,输入网上支付密码和验证码,验证通过后即可完成交易。因此,U盾保障之下的在线交易,如果使用的设备没有感染病毒的话,是非常安全的。因此,在一些对安全要求相对较高的应用场合,如网银交易、NT 工作站登录、电子钱包、电子政务、电子税务、电子报关、网上证券等,通过使用U盾,可以完全满足在线交易的安全性需求。

(三)生物特征识别认证技术

由于人的生物特征具有稳定性和唯一性,有研究人员提出可以采用生物特征识别技术代替传统的身份认证手段,构造新型的身份认证技术。生物特征识别技术主要指使用计算机及相关技术,利用人体本身特有的行为特征和(或)生理特征,通过模式识别和图像处理的方法进行身份识别。生物特征主要分为生理特征和行为特征:生理特征是人体本身固有的特征,是先天性的特征,基本不会或很难随主观意愿和客观条件发生改变,是生物特征识别技术的主要研究对象,其中,比较具有代表性的技术主要有指纹识别、人脸识别、虹膜识别等;行为特征主要指人的动作特征,是人们在长期生活过程中形成的行为习惯,利用该特征的识别技术,主要包括声音识别、笔迹识别等。

基于生物特征的识别技术较传统的身份认证具有很多优点,如保密、方便、不易遗忘、防伪性能较好、不易伪造或被盗、随身携带和随时随地使用等。也正是由于这些优点,很多国家已经在个人的身份证明证件中嵌入了持有者的生物特征信息,如嵌入指纹信息等。多个国家也在使用生物特征护照逐步替代传统护照。由Microsoft、IBM、NOVEL等公司共同成立的Bio API联盟,其目标就是制定生物特征识别应用程序接口(API)工业标准。

指纹识别是人们最容易接触到的生物特征识别技术,目前,大多数公司都采用指纹识别设备对员工的考勤进行记录,与原有的射频卡设别技术相比,指纹识别的优点在于避免了员工忘记携带射频卡的情况发生,同时也可以减少员工相互替代打卡的行为。人的指纹信息通常在出生约9个月后成型且终身不会改变,且不同人具有相同指纹的概率极低,这种稳定性和唯一性使指纹可以作为生物特征识别的对象。指纹识别主要通过采集手指末端纹路的图案信息对其进行识别,指纹中的谷、脊和纹路的起始点、分叉点、中断点、转折点、汇合点等特征点提供了大量且详细的信息,通过对上述这些特征信息的采集就可以达到辨别身份的目的。指纹识别是目前造价最低、易用性最高、应用最广泛的基于生物特征识别的身份认证技术。同时该技术已经被政府及司法部门所接受,在全球范围内都建立了犯罪指纹数据库和指纹鉴定机构,随着网络的互联互通,各国政府可以通过网络交换生物特征数据,确定犯罪分子位置,提前预警或实施抓捕,极大地打击了流动的国际犯罪行为。

指纹录入的过程主要包括:
(1)通过指纹识别器采集指纹图像;
(2)对采集的指纹图像进行预处理;
(3)提取指纹图像的特征信息;
(4)对特征信息进行编码或加密等处理;
(5)将处理后的特征信息录入数据库,与个人ID相绑定。

指纹识别的过程主要包括:
(1)通过指纹识别器采集指纹图像;
(2)对采集的指纹图像进行预处理;
(3)提取指纹图像的特征信息;
(4)对特征信息进行编码或加密等处理;
(5)将处理后的特征信息与数据库中的特征信息进行对比,如果找到相同的特征信息,返回个人ID信息或验证成功提示,否则,返回验证失败提示。

指纹识别技术的核心在于指纹识别算法的设计,而指纹识别算法的主要目的是在指纹图像上找到并对比指纹的特征。

指纹的特征分为总体特征和局部特征。总体特征主要指肉眼可以观察的特征,如纹型[环形(Loop)、弓形(Arch)、螺旋形(Whorl)等]、模式区(Pattern Area)、核心点(Core Point)、三角点(Delta)、纹数(Ridge Count)等;局部特征主要是指纹上节点的特征,两枚指纹可能会存在相同的总体特征,但其局部特征却不可能完全相同。通过对指纹纹路中出现的中断、分叉、打折点等特征点的确认,可以唯一地确定一个人的指纹信息。有英国学者提出,在考虑局部特征的情况下,通过对比特征点,只要发现13个特征点重合,就可以认为是同一指纹。

虽然指纹识别具有很多优点,但也有一定的技术缺点:某些人或某些群体可能因为指纹特征过少或纹路过浅等原因很难成像,造成指纹识别设备无法采集(或误采集);非加密的指纹采集数据信息可能会造成个人指纹信息的泄露,而该信息一旦泄露,也正是由于稳定性和唯一性,个人指纹信息可能会被滥用,造成一定的经济损失或更严重的问题;指纹采集设备需要与手指相接触才可以读取指纹信息,采集设备头表面会留下用户的指纹印痕,这些指纹印痕存在被复制的可能性,通过手模等技术同样也可以复制个人的指纹信息。

其他的生物特征识别技术还有虹膜识别。虹膜是一个位于眼睛瞳孔和巩膜之间的环状区域。人眼图像中,虹膜区域的冠状物、环状物、斑点、细丝、水晶体、射线、皱纹等形成了特有的纹理,是人眼的典型特征。人的虹膜结构十分复杂,可变项多达260多项,且在一生中几乎不会发生变化,具有非常高的稳定性、唯一性、非侵犯性、高准确性、防伪性等优点,也因此被认为是可靠性最高的生物特征识别技术。

虹膜识别的过程主要包括:
(1)通过全自动照相设备采集人眼虹膜图像;
(2)对虹膜图像信息进行预处理,包括归一化、增强等;
(3)提取虹膜图像的特征信息;
(4)对特征信息进行编码或加密处理;
(5)将数据库中虹膜模板的特征向量与待识别的虹膜特征向量进行相似性对比,如果相似度超过某一阈值,则认为两虹膜图像来自同一眼睛。

虹膜识别的优点:便于用户使用;由于低错误率和识别率,虹膜识别可能是目前最可靠的生物识别技术;虹膜识别技术无需使用者与虹膜采集设备接触,避免了个人虹膜信息的物理泄露,同时也避免了疾病的传播。缺点:虹膜识别目前还没有唯一性认证的试验;采集设备尺寸较大,对采集精度有很高的要求,且设备造价昂贵;容易受外界环境影响,如虹膜图像采集时需要外部有较好的光源,否则可能产生图像采集不清晰或图像畸变。

基于生物特征信息的认证是目前身份认证的一个流行趋势。由于生物特征的唯一性、普遍性、长久性等特点,使利用生物特征的身份认证优于传统身份认证方式,具有广阔的应用前景和市场潜力。采用生物特征为身份识别带来诸多优势时,由于其自身固有的一些性质,在实际应用中也会碰到很多非常严峻的挑战,特别是安全问题,如对生物特征信息的存储安全问题、对认证算法的安全性问题等,都有待于学者们进一步地研究解决。同时目前还没有一种生物特征识别技术能够达到完美无缺的要求,如眼睛病变可能会导致使用者的虹膜发生变化,无法采用虹膜识别对其进行身份认证。因此,采用人的多种生理特征和(或)行为特征,综合多种数据进行身份识别,可以避免单生物特征识别带来的问题,进一步提高生物特征识别系统的准确率和可靠性,也是生物特征识别技术未来的一个发展趋势。

四、对“机”的认证

这里的“机”是指具有智能处理能力的电脑设备和大型计算平台。相对于人来说,“机”具有更好的记忆,因此,可以使用高熵密钥实现认证。对设备认证的传统方法是“挑战—应答”机制。为了更好地说明“挑战—应答”机制的工作原理,假设A和B之间已经建立起共享密钥k。A要对B发起认证,因此A发送一个随机数r给B,B使用共享密钥k对r进行加密,然后将加密结果c作为应答发送给A,A使用共享密钥k也对r进行加密,然后比较加密结果是否与c一致,若一致,则对B的认证通过;否则认证失败。事实上,用于认证的加密算法不必要可逆,即不一定是有相应解密算法的加密算法,可以使用带密钥的消息认证码作为挑战应答过程中的加密算法。

上述方案只是实现“挑战—应答”认证机制的一种,可以有多种方法。典型的“挑战—应答”认证机制是移动通信中对用户的认证。下面以GSM的认证过程为例说明实际中的“挑战—应答”认证是如何实现的。

在GSM系统中,用户终端设备(UE)有一个用户注册域(HLR)和一个用户访问域(VLR)。用户UE和注册域HLR之间有一个共享密钥Ki,这个密钥在用户购卡时就建立了。在实际使用过程中,用户UE首先与访问域VLR联系,访问域VLR跟用户注册域HLR联系,得到认证向量,然后VLR将认证向量中的挑战信息发送给用户,用户UE根据挑战信息进行应答, VLR根据用户应答信息情况判断是否为合法用户。具体流程如图2所示。


图2 GSM系统中使用“挑战—应答”机制对用户的认证过程

在图2中,挑战信息RAND是一个随机数,对该挑战的应答信息RES是根据挑战信息RAND,使用共享密钥Ki和一种固定的密码算法A3计算得到的,RES=A3(Ki,RAND),XRES是用户注册域使用同样方法计算得到的,因此正常情况下应该满足RES=XRES。如果这一等式不成立,则请求入网的用户为非法用户,或哪里出了问题。另外,认证的目是为了数据的安全传输,因此,在GSM系统中,认证成功后会在用户UE和访问域VLR之间建立一个共享的临时会话密钥Kc=A8(Ki, RAND),以实现对接下来的数据通信(主要是语音)进行加密。

为什么要挑战应答呢?让用户终端直接告诉网络自己的身份不可以吗?当然不可以,因为终端会撒谎,不是终端设备撒谎,而是攻击者会假冒合法用户。如果使用共享密钥呢?如UE告诉网络说,“我是IDi,C=E(Ki,IDi)是加密确认”,其中,IDi是终端的真实身份,Ki是共享密钥,这看似也使用了共享密钥,但因为没有了挑战过程,传递的数据变成了恒定的,因此攻击者可以截获,然后实施重放攻击,即把截获到的信息(IDi,C)发送给网络,因为是合法密钥产生的C,当然可以成功假冒用户IDi。即使用户使用了随机数,也很难抵抗重放攻击。分析表明,使用“挑战—应答”是一种非常有效的抵抗重放攻击和许多其他假冒攻击的方法,但挑战信息的随机性或不可预测性对保证挑战应答机制的安全性是至关重要的。

五、对“物”的认证

这里的“物”与前面的“机”从物理实体上看没有本质区别,但对“物“的认证更需要强调轻量级属性。在物联网环境中,“物”意味着终端感知节点或RFID标签,这些“物”的资源有限,因此,不能使用传统的针对“机”的认证方法。那么,如何对“物”进行认证呢?回顾一下认证的目的就知道。对人认证的目的是让用户合法登录并使用有关的业务操作,包括一些服务的调用;对智能设备的认证在于建立安全通道,为接下来的数据传递提供安全保障。对物的认证其实也一样,认证的目的在于使数据能安全可靠地传递,这里的安全是指不被非法获取,可靠是指能鉴别假冒欺骗等行为。考虑到资源有限的“物”通常所传递的数据量也很有限,因此,对物的认证其实是对数据来源的认证,即一个数据无论经过多少转发,其原始来源应该可以得到鉴别。

为了说明轻量级认证与传统认证的区别,给出一个认证协议实例进行说明。图3的协议是一个对消息来源进行认证的协议,如果认证通过,则接受数据;否则进行异常处理。


图3 一种轻量级认证加密方案

在图3的认证加密方案中,IDA为A的身份标识;Ctr为计数器,可以是系统时钟,每次加密都将递增;k为A与B的共享密钥,通常为对称密钥,否则很难满足轻量级的要求。协议的执行无需信息交互,只需要A向B发送数据的同时,附带一些认证信息,当B收到A发过来的数据后,首先检查Ctr是否合法,如果是计数器,则与自己的记录进行比对;如果是系统时钟,则检测是否在允许的范围内。然后根据节点A的身份信息找到加密密钥k进行解密,解密后的Ctr与解密前的Ctr进行对比,如果一致,则接受解密后的数据,否则作为异常情况处理。

不难看出,图3的认证协议可以看作是轻量级认证协议。首先,数据交互次数最少;其次,当数据较小时,整个认证数据量可以包含在一个数据分组(或数据帧)内,也最少;最后,只需要执行一次加密算法操作。虽然这不是一个单纯的身份认证,但其中身份认证的过程是完整的。

从安全性上来说,轻量级认证协议的安全性低于传统的身份认证协议,只能提供短期的安全和抵抗低成本的攻击手段,这对许多物联网感知节点的安全性来说已经足够了。

六、其他身份认证技术

上述几种认证技术是根据认证对象来分的。下面根据认证方法的不同,介绍几种身份认证技术。

(一)数字签名技术

数字签名(Digital Signatures)是签名者使用私钥对待签名数据的杂凑值做密码运算得到的结果,该结果只能用签名者的公钥进行验证,用于确认待签名数据的完整性、签名者身份的真实性和签名行为的抗抵赖性。

数字签名是一种附加在消息后的一些数据,它基于公钥加密基础,用于鉴别数字信息。一套数字签名通常定义了2种运算,一个用于签名,另一个用于验证。数字签名只有发送者才能产生,别人不能伪造这一段数字串。由于签名与消息之间存在着可靠的联系,接收者可以利用数字签名确认消息来源以及确保消息的完整性、真实性和不可否认性。

(1)数据完整性:由于签名本身和要传递的消息之间是有关联的,消息的任何改动都将引起签名的变化,消息的接收方在接收到消息和签名之后经过对比就可以确定消息在传输的过程中是否被修改,如果被修改过,则签名失效。这也显示出了签名是不能够通过简单的拷贝从一个消息应用到另一个消息上。
(2)真实性:由于与接收方的公钥相对应的私钥只有发送方有,从而使接收方或第三方可以证实发送者的身份。如果接收方的公钥能够解密签名,则说明消息确实是发送方发送的。
(3)不可否认性:签名方日后不能否认自己曾经对消息进行的签名,因为私钥被用在了签名产生的过程中,而私钥只有发送者才拥有,因此,只要用相应的公钥解密了签名,就可以确定该签名一定是发送者产生的。但是,如果使用对称性密钥进行加密,不可否认性是不被保证的。

数字签名的实施需要公钥密码体制,而公钥的管理通常需要公钥证书来实现,即通过公钥证书来告知他人所掌握的公钥是否真实。数字签名可以用来提供多种安全服务,包括数据完整性、数据起源鉴别、身份认证以及非否认等。数字签名的一般过程如下。
(1)证书持有者对信息M做杂凑,得到杂凑值H。国际上公开使用的杂凑算法有MD5、SHA1等,在我国必须使用国家规定的杂凑算法。
(2)证书持有者使用私钥对H变换得到S,变换算法必须跟证书中的主体公钥信息中标明的算法一致。
(3)将S与原信息M一起传输或发布。其中,S为证书持有者对信息M的签名,其数据格式可以由国家相关标准定义,国际常用的标准有PKCS#7,数据中包含了所用的杂凑算法的信息。
(4)依赖方构建从自己的信任锚开始、信息发布者证书为止的证书认证路径并验证该证书路径。如果验证成功,则相信该证书的合法性,即确认该证书,确实属于声称的持有者。
(5)依赖方使用证书持有者的证书验证对信息M的签名S。首先使用S中标识的杂凑算法对M做杂凑,得到杂凑值H’;然后使用证书中的公钥对S变换,得到H"。比较H’与H",如果二者相等,则签名验证成功;否则签名验证失败。

数字签名可用于确认签名者身份的真实性,其原理与“挑战—响应”机制相同。为避免中间人攻击,基于数字签名的身份认证往往需要结合数字证书使用。例如,金融行业标准JR/T 0025.7《中国金融集成电路(IC)卡规范第七部分:借记贷记应用安全规范》规定了一种基于数字签名的动态数据认证(DDA)过程。动态数据认证采用了一个三层的公钥证书方案。每一个IC卡公钥由它的发卡行认证,而认证中心认证发卡行公钥。这表明为了验证IC卡的签名,终端需要先通过验证2个证书来恢复和验证IC卡公钥,然后用这个公钥来验证IC卡的动态签名。

(二)数字证书

数字证书也称公钥证书,是由证书认证机构(CA)签名的包含公开密钥拥有者信息、公开密钥、签发者信息、有效期以及扩展信息的一种数据结构。最简单的数字证书包含一个公开密钥、名称以及证书授权中心的数字签名。一般来说,数字证书主要包括证书所有者的信息、证书所有者的公钥、证书颁发机构的签名、证书的有效时间和其他信息等。数字证书的格式一般采用X.509国际标准,是广泛使用的证书格式之一。

数字证书提供了一种网上验证身份的方式,主要采用公开密钥体制,还包括对称密钥加密、数字签名、数字信封等技术。可以使用数字证书,通过运用对称和非对称密码体制等密码技术建立起一套严密的身份认证系统,每个用户自己设定一把特定的仅为本人所知的私有密钥(私钥),用它进行解密和签名;同时设定一把公共密钥(公钥)并由本人公开,为一组用户所共享,用于加密和验证签名。当发送一份保密文件时,发送方使用接收方的公钥对数据加密,而接收方则使用自己的私钥解密,通过数字的手段保证加密过程是一个不可逆过程,即只有用私有密钥才能解密,这样信息就可以安全无误地到达目的地了。因此,保证了信息除发送方和接收方外不被其他人窃取;信息在传输过程中不被篡改;发送方能够通过数字证书来确认接收方的身份;发送方对于自己的信息不能抵赖。

数字证书采用公钥密码体制,公钥密码技术解决了密钥的分配与管理问题。在电子商务技术中,商家可以公开其公钥,而保留其私钥。购物者可以用人人皆知的公钥对发送的消息进行加密,然后安全地发送给商家,商家用自己的私钥进行解密。而用户也可以用自己的私钥对信息进行加密,由于私钥仅为本人所有,这样就产生了别人无法生成的文件,即形成了数字证书。采用数字证书,能够确认以下两点:
(1)保证信息是由签名者自己签名发送的,签名者不能否认或难以否认;
(2)保证信息自签发后至收到为止未曾做过任何修改,签发的文件是真实文件。

根据用途的不同,数字证书可以分为以下几类。
(1)服务器证书(SSL证书):被安装在服务器设备上,用来证明服务器的身份和进行通信加密。服务器证书可以用来防止欺诈钓鱼站点。SSL证书主要用于服务器(应用)的数据传输链路加密和身份认证,绑定网站域名,不同的产品对于不同价值的数据要求不同的身份认证。
(2)电子邮件证书:用来证明电子邮件发件人的真实性。它并不证明数字证书上面CN一项所标识的证书所有者姓名的真实性,它只证明邮件地址的真实性。收到具有有效电子签名的电子邮件,除了能相信邮件确实由指定邮箱发出外,还可以确信该邮件从被发出后没有被篡改过。另外,使用接收的邮件证书,还可以向接收方发送加密邮件。该加密邮件可以在非安全网络传输,只有接收方的持有者才可能打开该邮件。
(3)客户端个人证书:主要被用来进行身份验证和电子签名。被存储在专用的智能密码钥匙中,使用时需要输入保护密码。使用该证书需要物理上获得其存储介质智能密码钥匙,且需要知道智能密码钥匙的保护密码,这也被称为双因子认证。这种认证手段是目前在Internet最安全的身份认证手段之一。

(三)匿名认证技术

匿名是指在一组由多个用户组成的匿名集中,用户不能被识别的状态。换言之,无法将这组对象中的用户或用户的行为进行任何关联。对象的匿名性必须是在一个对象集合中,以基于此类的对象集合组成一个匿名集合。例如,如果无法从一个发送者集合中找到信息的真实发送者,则实现发送匿名。匿名通信是指掩盖实际发生的通信链接关系,使窃听者无法直接获得或能够通过观察推测出通信参与方及参与方之间的通信链接关系。匿名通信的重要目的就是实现通信双方的身份匿名或者行动的无关联,为用户提供通信隐私保护和不可追踪性。匿名认证是指用户在证明自己身份合法性的同时能够确保自己身份信息、位置信息的匿名性。常见的实现匿名性的方法有零知识证明身份认证、假名认证等。匿名认证技术在RFID隐私性保护、智慧医疗系统的病例隐私性保护、网络投票有广泛应用。

实现匿名认证的另一种技术是零知识证明。零知识证明指的是证明者能够在不向验证者提供任何有用的信息的情况下,使验证者相信某个论断是正确的,即证明者向验证者证明并使其相信自己知道或拥有某一消息,但证明过程不能向验证者泄露任何关于被证明消息的信息。用零知识构造的身份认证协议可以在完成身份认证的同时不泄露任何身份信息,也就是实现了身份的匿名性。

(四)群组认证技术

群组认证是指证明方向验证方证明他是某个群体的合法成员,而验证者也只能验证该用户是否属于某个群体,不能知道证明者的具体身份。达到该目标的方法有群签名、环签名、集合认证等。

群签名就是满足这样要求的签名:一个群体中的任意一个成员可以以匿名的方式代表整个群体对消息进行签名。与其他数字签名一样,群签名是可以公开验证的,而且可以只用单个群公钥来验证,也可以作为群标志来展示群的主要用途、种类等。

环签名可以被视为一种特殊的群签名,它因签名按一定的规则组成一个环而得名。在环签名方案中,环中每个成员可以用自己的私钥和其他成员的公钥进行签名,却不需要得到其他成员的允许,而验证者只知道签名者来自这个环,但不知道具体的签名者。它没有可信中心、没有群的建立过程,对于验证者来说签名者是完全匿名的。环签名提供了一种匿名泄露秘密的巧妙方法。环签名的这种无条件匿名性在对信息需要长期保护的一些特殊环境中非常有用。

七、身份认证系统

在实际系统中,也有多种不同类型和适用于不同场景的身份认证系统。下面介绍几种有代表性的身份认证系统。

(一)Kerberos

1、Kerberos 基本原理
当一群用户在使用各自相互独立的计算机,而计算机之间没有网络连接时,与每个用户相关的资源都是可以通过物理方式来保护的。例如,操作系统可以使用基于用户身份的操作控制策略,通过鉴别客户的合法身份来允许用户使用操作系统。然而,当许多计算机工作站和分散的服务器通过网络连接起来组成一个分布式体系结构时,需要更复杂的安全认证方案来支撑。

Kerberos协议是20世纪80年代由MIT组织开发的一个公开源代码的网络认证协议,它是一种采用第三方作为认证中心的认证协议。Kerberos的命名来源于古希腊神话中地域之门守护者——长有3个头的狗Cerberus。在MIT开发的认证系统由服务方、被服务方以及第三方认证中心三部分组成,因而被贴切的命名为Kerberos。Kerberos,第一~三版未公开,直到第四版以后才公开。目前,已被开放软件基金会(OSF)的分布式计算环境(DCE)以及其他许多网络操作系统供应商采用。

Kerberos认证服务最初是用于MIT、IBM、Digital Equipment Corporation的联合开发项目Athena。Athena是一个针对教育科研使用的分布式计算环境,是一个典型的开放式网络环境。Athena计算环境由少量的中心独立服务器和大量的匿名工作站组成,工作站的主要工作是计算和人机交互。中心服务器提供文件存储、邮件收发、文件打印等一系列服务。而服务器限定只能够被授权的用户访问和使用,需要拥有验证服务请求的能力。但是在这样的环境中,它存在下列安全威胁:
(1)用户可以访问某些工作站,依赖这些工作站伪装成合法用户;
(2)用户可以改动工作站的IP地址从而伪装成其他的工作站;
(3)用户可以窃听工作站与服务器的交互信息,然后采用重放攻击非法进入服务器,获取服务。

在这样的一个环境下,所有的工作站、工作站系统、工作站地址以及任何网络中的物理设备都可能是不安全的,也无法信任。在整个网络中,任何人都可以有权在网络中读取、修改、插入数据等操作。在这种环境下,一般有如下几种方案可以采用:
(1)由客户端工作站确保用户或用户组的身份,由服务器提供基于用户标识ID的安全策略;
(2)要求客户端系统向服务器提供身份认证,相信客户端系统提供的用户身份;
(3)要求客户向服务器提供身份认证,同时需要服务器向客户提供身份认证。

在一个小型、封闭的环境中,所有系统属于同一个组织且被其访问,则应选择第一种方案或第二种方案。但对更为开放的网络互联环境而言,则应选择第3种方案保护用户信息和服务器资源。Kerberos支持第三种方案。Kerberos假设其体系机构为分布的客户/服务器体系结构,并拥有一个或多个Kerberos服务器提供认证服务。


图4 Kerberos 结构

如图4所示,Kerberos协议由以下3个部分所组成。

(1)密钥分发中心(Key Distribution Center)。KDC服务器有2个部件:Kerberos认证服务器(AS,Authentication Server)和一个授票服务器(TGS, Ticket Granting Server)。TGS和AS是2个独立的结构,在实际的部署过程中,可以是一个AS服务器和多个TGS服务器共同存在。
(2)客户端(Client)。需要向Server请求服务的被服务方。
(3)服务端(Server)。向授权客户提供服务的服务方。

当客户端准备向服务端请求服务时,它需要向KDC申请一个访问的Ticket,也就是常说的“票据”,客户端将获得的票据发给服务端请求身份验证。服务端验证通过才会向客户端提供服务。总体来说,完整的Kerberos认证过程包括了3个部分:
(1)服务交换认证,该过程主要完成客户端从AS访问一个TGS的许可票据;
(2)服务票据交换,该过程则是客户端从TGS获取一个访问服务器的许可票据;
(3)客户/服务器认证交换,即客户和服务器之间的认证过程,通过认证后客户方可获取服务。


图5 Kerberos认证过程

如图5所示,一个完整的Kerberos(V4版)认证过程分以下几个步骤。
(1)客户端首先向AS发送一个请求访问TGS的票据,客户端发送的内容即C→AS:IDv||IDTGS||TS1;其中,IDv代表客户端的用户标识信息,IDTGS是要求访问的TGS标识,TS1是客户端产生信息时的时间戳,它被提供给AS服务器用来验证客户端时钟是否与AS时钟同步。
(2)AS接收到请求后,在服务器的数据库中查询与该客户端相关的信息,如共享密钥 Kc(这些信息在客户注册时生成并保存在AS服务器中)。AS根据口令 Kc临时派生一个会话密钥Ktmp。AS利用客户实体信息、TGS信息、时间戳以及生存期,连同会话密钥组合生成一个票据分配许可证(TGT,Ticke-Grant-Ticket)。AS利用与TGS共享的密钥Ktgs加密TGT,即:最后AS使用Kc将会话密钥Ktmp、时间戳、TGS信息连同TGT加密返回给客户端。即:至此,客户端与AS完成了服务认证交换的过程,客户端获取了访问TGS的授权票据。
(3)客户端收到AS的回复后,利用自己的口令解密获得临时会话密钥Ktmp的票据TGT。客户利用Ktmp和访问TGS对自己信息和时间戳加密生成一个认证单Authenticator,连同请求目标服务器信息和AS授权的TGT票据一同发送给TGS。即:
(4)TGS收到客户的请求信息后,利用共享密钥Ktgs解密TGT,获取其中的会话密钥Ktmp解密认证单Authenticator后对TGT和Authenticator中的信息进行对比。对比验证通过后,TGS根据客户和服务端的信息生成一个客户与目标服务器进行通信的临时会话密钥Kc−s。TGS利用客户信息、目标服务器的信息、时间戳、生命周期等信息连同Kc−s生成一张访问目标服务器的票据Tickets。然后,采用服务器与TGS共享的密钥Ktgs−c对该票据进行加密,最后结果即:最后TGS利用会话密钥Ktmp将客户/服务器会话密钥Kc-s、访问服务器的票据Tickets以及客户和服务器的信息加密返回给客户,即:至此,客户完成了和KDC的服务授权票据交换过程,客户将获得最终访问目标服务器的票据和会话密钥。
(5)客户接收到TGS返回的分组后解密得到与服务器临时会话的密钥和访问服务器的票据Tickets。客户利用自己的信息再生成一张新的认证单Authenticatior,并用与服务器通信的会话密钥Kc−s加密该认证单。然后,客户将新的认证单连同授权票据Tickets作为服务认证请求发送给目标服务器Server。
(6)服务器收到客户的认证请求后,对票据Tickets解密获取会话密钥,再利用该会话密钥解密认证单。服务器对解密后两者的信息进行比对,如果比对一致,则客户的认证请求通过。与此同时,由于只有正确的服务端才能解密并获取到正确的会话密钥,因此该过程也是客户对服务器的验证,如果是完整的双向认证,此处服务器将返回一个确认认证的信息给客户,该信息是利用Kc−s对客户认证单上的时间戳加1的结果进行加密。客户接收到该结果后解密可获得一个时间增加的时间戳,由于该消息是加密消息,客户端因此可以该消息只能是目标服务器才能发来,从而进一步确定服务器的身份。此后,服务器和客户之间通过共享的临时会话密钥Kc−s建立秘密通信信道。

从上述(1)(6)的认证过程来看,客户与服务器之间的认证在KDC的一次参与下便可实现双向认证,相比传统的认证服务,Kerberos具有较高的性能,并且也实现了双向认证。在(1)(2)过程中,尽管客户是用明文向AS请求TGT,但并不影响认证的安全性,一方面只有拥有正确口令的客户才可解开加密的回复,另一方面这种方式避免了用户口令在网络中传输,反而提高了系统的安全性。在(1)~(6)的认证过程中,所有票据都添加了生命有效期,添加有效期的作用是若票据没有有效期,则用户每次访问都需要申请新的票据,导致用户在一段时间可能需要多次要求提供口令,不利于用户的体验。反过来,若票据一次申请、长期有效的话则容易遭受攻击,也容易导致信息泄露。

由于客户发送给目标服务器的票据是明文传输的,票据在传输过程中容易为敌手所截获并重用。因此在票据的基础上,用户添加了一些用于认证的消息即认证单,认证单中包括了时间戳,该时间戳表明票据被传送的时间,整个认证单被会话密钥所加密。在传输过程中,敌手尽管可以截获到票据,但是由于认证单是加密的,敌手无法解开认证单并篡改时间戳,从而抵抗了敌手的重放攻击。在上述的Kerberos认证过程中也可以看出,AS和TGS是2个相对独立的服务,它们可以部署在同一个服务器上即KDC,也可以存在一个AS服务器和多个TGS服务器独立分布在网络中。同样,Kerberos认证过程中不依赖除AS和TGS以外的客户主机操作系统以及网络上所有主机的安全性能,也不依赖主机的地址是否可信。因此,Kerberos是一个可信度高、适用于各种环境的认证协议。

2、Kerberos V5的改进
Kerberos V4 是MIT针对Athena项目开发的认证协议,因此,V4存在诸如系统、协议依赖的缺陷。V5版本针对V4中的一些缺陷和问题做出改善,从而形成通用版的Kerberos,现在V5版本已经成为IETF的标准。与V4比较,Kerberos V5在以下几个方面做了一些改进。
(1)认证流程,V5与V4的认证流程即消息交换的步骤基本一致,V5版本对客户—服务器之间的认证交换做了些许改进,V5允许客户选择是否验证服务器,同时添加了子密钥和序列号2个内容,前者可以替代原来的临时会话密钥,后者防止重返攻击。
(2)票据内容,V5在V4的基础上添加了若干新的票据内容,例如,Realm标识用户域(这在Kerberos跨域认证中使用),Nonce标识是临时交互号确保交互流程的安全。
(3)票据标识,V5版本中添加了标识域,标识域内容提供了许多种类的功能,有些功能为用户所需,有些则是Kerberos服务开启和关闭的控制位。例如,INITIAL标识表示一个票据是AS所发布的而非TGS发布。INVALID标识代表一个票据是无效的,带有该标识的票据将会被应用服务器拒绝接受。

3、多Kerberos域的跨域访问
Kerberos协议支持在多个Kerberos域之间的跨域访问。如图6所示,域A和域B是以Kerberos协议作为认证机制的2个网络环境,每个域包括一个Kerberos服务器,该服务器维护了该域内所有用户的共享密钥信息和所有服务器的共享密钥信息。这样的域也称为Kerberos域。Kerberos协议提供在多个Kerberos子域之间的跨域访问,前提条件是2个子域的Kerberos服务器应该相互在对方系统上注册,也就是说2个Kerberos服务器应该共享一个通信密钥。


图6 Kerberos跨域认证访问

如图6所示,当域A中的客户C希望访问域B的应用服务器S时,A首先向本地的Kerberos服务器申请访问域B的TGS的远程授权票据,获得授权票据后,C向域 B的Kerberos服务器发送请求访问S的票据,通过验证后,Kerberos服务器返回访问S的授权票据,最后C可以携带域B Kerberos签发的票据访问远程服务器S。访问流程的细节描述如下。
(1)C请求TGT C→AS:ID v||ID TGS||TS 1
(2)授权TGTAS→C:E(Kc,Ktmp||IDc|IDTGS||TS2||LifeTime2||Tickettgs)
(3)申请访问域BKerberos的票据:C→TGS:ID c||TGT||Authenticatior||TS 3
(4)授权访问票据:TGS→C:E(K tmp,K c−TGSrealm||ID TGSrealm||TS 4||Ticket TGSrealm)
(5)请求访问S的票据:C→TGSrealm:ID c||Ticket TGSrealm|Authenticatior
(6)域B Kerberos授权票据:E(K c−TGSrealm,K c−s||ID S||TS 6||Ticket s)
(7)请求S服务器验证C→S:ID c||Ticket s|Authenticator
(8) 确认客户端,S→C:E(K c−s,TS 7)

从上述过程可知,任何2个子域之间的访问比单个子域内的访问多两步,性能影响不大。但是这种多域之间跨域访问的方式需要任意2个Kerberos服务器之间相互注册并维护这些通信密钥,其复杂度随着子域数的增长成O(N2)。

4、Kerberos认证协议的优缺点
综上所述,与传统的认证协议相比,Kerberos协议具有一系列的优势。首先,它支持双向的身份认证,大部分传统的认证协议都是基于服务器可信的网络环境,往往都是只验客户,但客户无法验证服务器。而Kerberos则没有这样的前提,正如之前所说,Kerberos协议中只有AS和TGS是可信之外,网络的所有工作站、服务器都是不可信的。当用户与服务器进行交互时,Kerberos为客户抵挡了网络恶意攻击和欺骗。其次, Kerberos实现了一次性签放,在有效期内可多次使用。假如用户在一个开放网络环境中需要访问多个服务器,如查询邮件、打印文件、访问FTP等都在不同的服务器上,用户可以通过AS申请TGS的票据后,在有效期内利用该票据与TGS多次请求不同访问授权票据。降低用户输入口令次数,从而提高了用户的体验。最后,Kerberos提供了分布式网络环境下的域间认证机制,Kerberos允许客户花费少量的资源即可访问其他子域的服务。这一点传统的认证协议难以实现。

但是,Kerberos协议也存在一些不足和安全隐患。Kerberos身份认证采用的是对称加密机制,加解密都需要相同的密钥,交换密钥时的安全性不能保障。Kerberos协议对时钟的要求比较高,必须是在时钟基本同步的环境中,如果引入事件同步机制则又需保证同步机制的安全;若时间不同步,攻击者可以通过调节时钟来实现重放攻击。在Kerberos中,客户信息和服务器认证信息都集中存放在AS服务器中,使Kerberos的安全严重依赖于AS和TGS的性能和安全。随着用户数量的增加,Kerberos需要维护复杂的密钥管理,这往往比较困难。

(二)公钥基础设施(PKI)

根据前面的论述,身份认证的目的是要确定对方的身份是否真实或合法。为了达到这一目的,需要建立初始信任。但在网络环境下,建立信任意味着建立一条安全通道(单向的或双向的)。这一任务在公钥密码提出之前非常困难、代价很高。公钥密码提出后,人们可以通过公钥密码手段传递秘密密钥,但公钥的真实性又难以保证。为了满足网络环境陌生人之间安全通信的需求,通过可信第三方的公钥基础设施被提出来,这样当陌生的A与B想要建立一条安全路径时,可以寻找共同信任的第三方,在可信第三方的帮助下实现A对B所拥有的公钥的鉴别,从而建立从B到A的安全通道。

简单地说,公钥基础设施就是让可信第三方对用户的公钥签署证书,只要验证公钥证书的合法性,就可以相信公钥证书中所描述的公钥属主信息。

在通信双方A与B互不信任的情况下,要想使B确信某个公钥的确是A的公钥,必须有一个B信得过的第三方T向B证明,而T又必须有能力知道该公钥的确属于A,从而可以向B提供真实信息。为了使这种证明可以离线工作,即不必要由T亲自向B证明,只要T预先出具一个证明,A通过向B提供这个证明即可。这种证明就是公钥证书。更确切地说,公钥证书是一个用户都信任的称为证书签署中心(CA)的第三方向每一个合法用户的公钥签署一个证书,该证书包含用户身份信息(如IP地址)、用户公钥信息、证书的签发时间和有效期等信息。CA对这些信息进行数字签名,该签名就是公钥证书。任何人收到这样一个公钥证书后,通过验证CA的签名是否合法以及证书是否还有效,就可知道证书中所包含的公钥属于谁。

为了能验证CA的签名,用户应该知道CA的公钥信息。如果用户不知道CA的公钥,即认为这是系统外的用户,不予考虑。系统中的用户知道CA的真实公钥是最基本的信任假设,缺少这个假设任何其他信任都很难建立起来。读者可能还有一系列的问题,如CA为什么要为用户签署公钥证书?答案很简单:CA是服务机构,或者是赢利机构,而用户是他的客户。CA如何知道用户提供的公钥是真实的?这一点毋庸置疑,因为没有哪个用户用别人的公钥作为自己的去申请证书,那样只能给别人提供攻击自己的机会。那么CA如何知道用户的身份是真实的?这一点需要各个CA去掌握。在许多应用环境中,CA对用户提供的身份信息需要通过另外的途径去验证,如电话确认或让用户离线注册。

最后的问题是由谁来作CA。同样的回答是看具体情况。但不管是哪种情况,在整个世界都被Internet连接在一起的今天,没有谁能作全世界的CA,因为如果存在这样一个CA,它对用户的身份确认就是个问题,而且要服务世界范围内的用户,负担也太重,而且一旦网络出现问题或CA的服务器遭受攻击,所造成的损失太大。为了解决世界范围内,或者至少在较大范围内(如一个国家)能对公钥签署证书,公钥基础设施(PKI, Public Key Infrastructure)应运而生。PKI是一种签署和管理公钥证书的标准体系,它看起来似乎是件容易的事,但具体成为标准的话需要考虑很多方面的问题,如证书格式、证书的撤销和更新过程、证书的存放和查询、证书的验证,特别是跨CA证书的验证等。

PKI的原理简单描述如下。假定有一个证书签署中心(CA,Certification Authority)、一个证书注册中心(RA,Registration Authority)、一个复杂的存放证书的公共数据库。证书的签署和使用等包括下列几个过程。
(1)证书签署:用户向CA证明自己的合法身份并提供公钥,CA对此公钥签署公钥证书。用户可以对公钥证书进行正确性验证。用户的公钥证书可以证明该公钥属于该用户,需要使用该用户公钥的人都可以在获取该证书后进行验证以确信公钥是真实的。
(2)证书存放:如何让其他需要使用该证书的用户得到该用户的公钥证书呢?最直观的方法是向该用户索取,但该用户并不是总处于在线状态,即使在线,也不一定能随时应答索取公钥证书的询问;另一种方法是将用户的公钥证书放在自己的个人网页上,但问题是并非所有用户都有自己的个人网页,即使有个人网页,需要使用该证书的用户也不一定容易找到该个人网页。因此,PKI的解决方案是将公钥证书放在一个标准数据库中,需要使用公钥证书的用户可以到该数据库查询。因此,当用户在申请到公钥证书时,需要到RA那里去注册, RA验证证书合法性后,将证书连同用户信息存放在证书数据库中。
(3)证书注销和更新:尽管公钥证书有其有效期,但由于各种原因,一个公钥证书可能在有效期内就需要更换或注销。当用户申请注销公钥证书时,用该公钥对应的私钥对一个固定格式的消息进行数字签名并传给RA,当RA验证签名合法后,将证书从数据库中删除,同时在一个叫做证书注销表(CRL)的数据库中添加被注销的证书信息。当用户需要更新自己的证书时,选取一个新的公钥,用原来公钥对应的私钥对新公钥进行签名,将签名信息传给CA,CA验证签名有效后签署一个新的公钥证书。用户再将该新公钥证书连同用原私钥签名的证书更新请求传给RA,RA在验证签名以及新证书的合法性后,将原来的证书从数据库中删除,添加新证书,同时在证书注销表中添加被注销的证书信息。
(4)证书的获取:当其他用户需要某个用户的公钥证书时,向 RA 提出咨询请求。RA根据请求所给出的用户信息查找到公钥证书,然后将公钥证书传给咨询者。有时候,咨询者已经有某个用户的公钥证书,只想查看一下该公钥证书是否仍然有效,对这种需求,RA 只需检查CRL中是否包含所咨询的公钥证书的信息即可。为查询方便,每个公钥证书都有一个身份标识,因此,查询有效性时不需要把整个证书数据在网上传输,只需要传输证书的身份标识以及其是否被注销的信息即可。
(5)证书的验证:当得到某个用户的证书后,需要验证证书的合法性,以确定证书中所含的公钥信息的真实性。当验证者和证书持有人有相同的CA时,这个问题很容易解决,因为验证者知道CA的公钥信息,通过验证CA在证书上的数字签名,即可确定证书的合法性。但是,当验证者和证书持有人没有相同的CA时,这个问题就变得复杂多了。正如前面的讨论,单一CA的假设是不合理的,在大的应用范围内,必将由多个CA来完成证书签署工作。但RA和证书数据库可以只有一个,或在逻辑上只有一个,即实际分布式的数据库,使用的用户感知不到它的结构。对多个CA的情况,有几种不同的架构:自上而下的树状CA结构、双向树状CA结构、平级CA结构。下面分别简单介绍。

①自上而下的树状CA结构
有一个种子证书签发中心CA,它负责给一些子CA(如CA1,CA2,…,CAn)发放公钥证书。每个CAk又负责给自己的一些子CA(如CAk1、CAk2等)发放公钥证书。这样经过几层后,枝端的CA给用户发放公钥证书。这种树形结构如图7所示。


图7 自上而下的树状CA结构

如图7所示,箭头表示发起端给指向端签署发放公钥证书。假设所有用户拥有种子CA的公钥信息。当一个用户得到另外某个用户的公钥证书时,自上而下进行验证。比如,当用户A得到用户X的公钥证书后,需要用CA的公钥来验证CA2的公钥证书的合法性,然后从CA2的公钥证书中得到CA2的公钥信息,再由此验证CA22的公钥证书的合法性,然后从CA22的公钥证书中得到CA22的公钥信息,再由此验证X的公钥证书的合法性,最后提取X的公钥信息。

自上而下的树状CA结构有其明显的缺点。首先,假设所有用户拥有CA的公钥信息有点困难,不是技术上做不到,而是假如让该系统在一定范围内使用,特别是在世界范围内使用,在哪里设置CA比较现实,这可能会遇到一些诸如政治因素等障碍。另外,即使A要验证C的公钥证书,也要通过自上而下的复杂过程,而通常的证书验证所跨越的CA数很少,因此,应该找到能使近距离证书验证更方便的方法。于是有了双向树状CA结构。

②双向树状CA结构
双向树状CA结构与图7类似,但区别是连接2个CA的箭头的方向是双向的,即除了图7中表示的所有证书外,CA1还为CA签署一个证书,同样CA2,…,CAn也分别为CA签署一个证书。类似地,每个其他的子CA也为它们的父CA签署一个公钥证书。CA1为CA所签署的公钥证书不是直接为CA的用户使用的,而是为了在该结构所连接的任何2个叶子用户(如图7所示的最底层的用户)之间建立一条信任路径,通过这条信任路径,用户之间可以相互验证公钥证书,而所有用户只需要拥有它们的直接CA的公钥即可。用一个例子说明用户A如何验证用户C的公钥证书。从图7以及上述的修改描述中可以看出,用户C的公钥证书是CA12签发的,因此,用户A必须得到CA12的真实公钥才能验证。但用户A并不掌握CA12的公钥,但可以得到CA12的公钥证书,从图7可以看出,这个证书是CA1签署的。同样,用户A并不掌握CA1的公钥,但可以得到CA1的公钥证书。CA1的公钥证书至少有2个,一个是CA签署的,一个是CA11签署的。用户A因为掌握CA11的公钥信息,因此需要由CA11签署的那个公钥证书。这样,用户A可以用CA11的公钥验证CA1的公钥证书,然后,提取公钥信息后用以验证它所签署的 CA12的公钥证书,然后再提出公钥信息后用以验证它所签署的用户C的公钥证书。注意从用户A到用户C有一条最短的连通路径,因为连接的CA之间有相互的公钥证书,因此,可以不经过CA就完成对用户公钥证书的验证。另外,对CA的信任假设也更合理,所有用户只需要信任当地的CA,而用户的身份也由当地的CA来确认。这里所说的信任是指掌握真实的公钥信息并确信这一事实。这是比较实用且被推荐的方法。

③平级CA结构
上述双向树状CA结构仍然有缺点,比如,当某一个CA需要更新证书时,所有与其连接的其他CA都需要更新公钥证书。但其在实用方面已经比自上而下的树状CA结构改善了很多。但不管哪种结构,都需要整个结构是连通的,即存在从用户所信任的CA出发到所要验证证书的用户的一条信任路径。但是,在公钥证书体系的建立过程中,其结构是逐渐形成的,而且会有很多小的独立的CA结构,当发展到一定规模后,这些CA结构之间需要互通,但又不便于找到一个更高层的机构作为它们共同的CA。怎么办呢?因为各个证书结构之间内部是连通的,只要在不同的结构之间塔起一架桥梁,就可以使2个结构互通。因此,可以选取各个结构中的最高层CA作代表,2个代表之间互相签署公钥证书,这样,就将2个结构连通了。如果多个结构希望做到互通,只要选取每个结构的最高层CA代表,使这些代表之间两两建立信任连接(即相互签署公钥证书),就可以将这些结构都连通起来。这种连通起来的结构称为平级CA结构。平级CA结构的优点在于,不管各个证书结构的内部是怎么运行的,通过最高层的CA互通,可以使任何一个结构中的任一用户能够验证另外任何一个结构中的任何用户的公钥证书,当然验证方需要知道各个CA结构的内部结构(比如,是自上而下的树状CA结构还是双向树状CA结构)以实施验证步骤。

八、身份认证应用案例

近年来,互联网技术进入史无前例的发展和增长阶段,大量传统的业务系统也逐渐开始采用网络化、信息化的处理方式。这导致越来越多基于网络环境的应用系统不断涌现,系统的复杂程度和业务的特性与多样化的需求有着直接的关系。各式各样的应用系统不断提高了大型企业、高校、国家机构单位员工办公的效率,也极各样的应用系统不断提高了大型企业、高校、国家机构单位员工办公的效率,也极大地便利了企业管理。然而,随着需求的不断扩大,企业内部相对独立的系统数量在不断增长,例如,在高校里常有选课系统、图书馆管理系统、一卡通系统、教务系统等;在大型企业里有办公自动化系统(OA)、ERP系统、绩效管理系统、员工管理系统以及CRM系统等。然而,由于这些系统都是相对独立部署和独立使用,随着应用系统数量的不断增加,用户不得不牢记多套用户名和口令。

实践表明,过多的系统登录认证会导致用户出错的可能性不断增加。过多的登录错误次数可能导致非法截获和破坏。为了应对这些情况,应用系统管理员通常会增加更多的安全措施,提高系统的复杂性,但也导致系统的可用性不断下降。对于用户而言,为了尽量减少登录出错,提高工作效率,用户一般会降低口令的复杂度,甚至对所有系统设置最简单的口令进行登录、甚至多个业务系统均采用同样的口令。这样反而降低了系统的安全性,危及到企业的安全。

为了解决这些安全现状,统一身份认证与单点登录技术被提出并逐渐得到广泛的认可。下面结合一个企业内部统一认证管理系统实例,整体了解统一身份认证系统的原理和结构。

(一)统一身份认证管理与单点登录技术

统一身份认证管理的原则是将多个应用系统的用户身份管理与该应用系统的业务剥离开来。多个应用系统的身份管理统一到身份认证管理平台,由该平台负责用户的身份管理、用户权限管理以及用户登录。这就是所谓的统一身份认证管理平台。当用户需要访问应用系统时,可以首先登录到统一身份认证管理平台,由统一身份管理平台颁发访问的票据给目标应用系统。用户只需在通过统一身份认证平台后,由身份管理平台负责与应用系统进行认证交互。在应用层面上,用户一次登录便可无缝访问多个应用系统,大大降低了用户操作的复杂度,其优越性不言而喻。

图8是一个典型的采用统一身份管理与认证的分布式访问网络结构,应用系统1到应用系统n是相互独立的应用服务系统。所有应用系统前置统一认证平台,认证平台包括了集中化的身份管理、集中身份认证、集中访问授权和集中化审计管理。集中身份管理的好处在于可以实现对用户在系统中的生命周期的统一管理,同时也可以建立与其他应用系统的同步机制,管理员可以做到“一次修改,全部生效”的能力。同样地,采用集中化身份管理方式帮助用户摆脱了记忆多个用户名/口令的痛苦,降低用户操作的复杂性。另外,统一身份管理平台有利于管理员实现集中化的访问授权管理,也可以做到“一次授权,随处可用”的目的。


图8 统一身份认证和单点登录模型

在统一身份管理的基础上,用户可以通过登录到统一身份认证平台,由统一身份认证平台向应用系统颁发访问票据,从而达到用户一次登录、随处无缝访问的效果,当然前提条件是应用系统对认证管理系统的完全信任。这种方式被称为单点登录(SSO, Single Sign-On)。单点登录技术拥有诸多的优点,首先,它大大地提高了用户的工作效率,用户无需再记忆大量的用户名和口令;其次,SSO提供了系统的安全性,简化了系统管理员的工作。用户的认证信息统一在认证平台中保存,方便管理员实现集中授权、身份集中管理。最后,SSO提供了一套相对完整的身份认证框架,可扩展性强,能够使系统在研发过程中提高效率,同时也保证了系统的安全性能。

目前,基于这种统一身份管理的单点登录技术大致可以分为以下几个类型。
(1)第一种是如本章描述的Kerberos认证协议机制,Kerberos系统以KDC为信任中心实现对多个服务器的访问。用户先通过Kerberos AS服务的验证后获取到TGS服务器的票据,在访问应用服务器时,用户无需再次登录,仅需携带TGT访问TGS服务器以获取访问目标服务器的Ticket。服务器通过验证票据以确定客户的合法身份。Kerberos的特点是典型的集中式身份管理方式,并且是由客户主动发起票据请求后才可访问应用服务器。而应用服务器无需和认证中心进行确认。
(2)第二种类型是基于Web服务的单点登录技术,如微软的Pass Port。这种单点登录技术的特点是采用Web技术的特点。用户向某个应用服务器发送访问请求时,运行在该运行服务器上的访问控制请求检查到用户没有登录则将用户重定向到统一身份认证平台,用户通过身份认证后,认证服务器将生成Cookie(包含了用户身份验证标识),并发送票据TGT(包含用户唯一标识符PUID和时间戳)。用户浏览器携带Cookie和TGT访问应用服务器,如果应用服务器可以成功解密cookie并核对身份则认为该用户是合法用户,从而访问成功。
(3)联盟方式,Liberty Aliance 自由联盟由近30个组织于2001年11月创立,Libtery Aliance 建立了一种开放的、标准的、易于实现的统一身份管理方法。Liberty Aliance 是一种完全针对开放式网络、跨域的分布式统一认证方法,用户只需要使用在任何域的任何设备登录并通过联盟的身份验证之后,就可以访问多个Web站点,无需重复认证。当用户向某联盟站点访问时,若检测到没有登录,Web 站点将用户重定向到本地的联盟服务器上,如果本地服务器发现该用户不存在则会将用户定向到用户所在域的联盟服务器上。联盟认证服务器在验证了用户的身份后将生成一个SAML断言返回给用户。用户将SAML断言交给本地认证服务器,之后本地服务器将为本次访问创建Cookie,并将用户重定向到访问站点上。

目前,统一身份认证平台得到了广泛的应用,比较著名的有Microsoft 的.Net Passport,基于J2EE体系结构的Pubcooie、Web Auth、JOSSO(JAVA Open Single Sign-On)等。市场上商用的统一身份认证平台比比皆是。但是总的来说,统一身份认证平台的基本原理和结构相对比较类似,而具体选择什么样的身份管理方式和认证方法则依赖于真实的环境需求。

(二)UNIT认证系统的基本结构

图9是UNIT认证系统的整体结构,UNIT认证系统为大型企业内部的多个应用系统提供统一身份管理和单点登录服务。UNIT采用PKI基础设施为基础,建立以数字证书为信任基础的身份管理体系,融合集中授权、集中审计等功能,从而实现对内部系统用户的全面管控。当然,鉴于UNIT的架构特性,也可以提供外域认证的服务。


图9 统一身份认证平台结构

(1)统一用户管理。在统一身份认证系统中,核心数据是用户的身份数据,是实现认证管理和访问控制的基础。由于企业内部的应用子系统相对独立,并且安全要求和实现架构各有不同,为了满足松散性、易兼容、易扩展的要求,UNIT 系统采用主账户—多子账户的身份映射特点,用户可以将自己在每个应用系统中的子账号映射到统一身份认证平台的主账号上,由主账号代理登录应用系统(如图10所示),这种映射方式十分有利于现有系统的改造和新的应用系统快速接入。在UNIT系统中,每个用户都有一张唯一标识的数字证书与之对应,为用户在登录时提供双向的身份认证服务。为了存储这种映射关系方式,也便于在单点登录时实现快速查询,UNIT采用LDAP(Lightweight Directory Access Protocol)目录服务存储用户信息。LDAP目录以树状的层次结构来存储数据,非常符合企业系统的结构。通过LDAP的映射关系,用户即可实现一次登录、多次有效的功能,同时也依靠LDAP实现对应用系统的访问权限控制和用户生命周期维护管理功能。


图10 账户映射关系

(2)统一证书管理。采用数字证书作为用户认证方式的统一身份管理系统集成证书管理服务,包括用户证书的申请、审批、核发、更新、吊销等生命周期。系统也可以不直接实现这一系列功能,并有第三方CA机构复杂办法和管理证书。为了安全的保存用户证书,用户手中一般都配备USB Key。另外,对于机密性要求高的环境,可以采用SSL建立专用秘密传输通道以提高平台的安全性。

(3)统一管理认证。实现多业务系统的统一认证,为企业提供单点登录服务,用户只需要登录一次就可以访问所有相互信任的应用系统。由于单点登录涉及到对很多访问权限的授权,因此,保证单点认证过程的安全是非常重要的一点。确保做到这点的一个方法是用数字证书来代替静态的用户名密码对。数字证书为每次登录生成不同的一次性使用的密码,并且将生成的密码安全地在网络上传输,这使攻击者实际不可能发现可使用的密码。基于证书的认证还防止绕过系统直接登录到次级系统的企图,用户名密码对也被加密以防止监测攻击。系统还可以支持两重或三重认证,将密码、证书、生物特征认证工具组合在一起使用。

(4)统一授权管理。根据企业安全策略,采用基于角色的访问控制技术,实现支持多应用系统的集中、灵活的访问控制和授权管理功能,提高管理效率。

(三)UNIT认证系统的身份认证

统一身份认证平台是企业内部系统安全登录的基础,只有安全的认证机制才可以保证企业大门不被非法人员进入。图11给出了UNIT认证系统中一个用户访问应用系统的示意,用户首先必须通过统一身份认证平台的身份认证才可获得访问令牌从而无缝访问多个应用系统。


图11 统一身份认证平台的登录与身份认证

为了提供便利的多样化身份认证方式,统一身份认证平台一般支持多种常用的身份认证方法,包括用户名/口令、数字证书、Windows域认证、通行码,当然,认证的方式不仅仅局限于这几种,也可以根据用户的具体需求对认证方式进行扩展。UNIT 身份认证系统采用多因子认证技术保障用户的安全登录。如图12所示,UNIT采用静态口令、智能卡、生物识别的多因子强认证技术实现身份认证。


图12 强身份认证方式

(1)用户名/口令认证
用户名/口令的方式认证用户身份是目前最普遍的认证方式,静态口令虽然是弱类型的身份认证,但是有技术结构简单、成本低的缺点,可以用于安全性相对需求不高的资源访问。例如,在查看个人信息时可以要求用户输入口令。

(2)智能卡认证
UNIT 采用了数字证书作为身份信赖,用户不但可以通过数字证书完成身份认证,还可以进一步进行安全加密,数字签名等操作。在本系统中,采用智能卡作为存储介质,可以安全存储用户的证书,在登录时可要求验证用户的数字证书,从而实现强身份认证。例如,用户在进行单点登录时可以使用智能卡作为认证的前置条件。在涉及企业交易业务时,可采用数字证书进行签名、验签。

(3)生物识别
为增强认证的安全性,UNIT 也采用了生物识别技术,如指纹识别,目的是进一步加强对用户的认证。

(四)UNIT系统的单点登录

单点登录访问的实现方式有多种,一般可以分为软件代理登录和硬件网关级登录2种。软件代理登录的方式是指采用插入式软件模块自动为用户实现登录,如 Web 拦截器(Intercepting Web Agent),Web拦截器是一种基于过滤技术(Filter)的应用防火墙。使用Web拦截器在请求到达之前拦截请求,并在应用外部提供认证和授权。如图13(a)所示,Web拦截器可以安装在Web服务器中,通过在Web服务器上拦截入站请求和执行访问控制策略对入站请求进行认证和授权。

硬件网关级单点登录采用前置硬件网关系统,从网络上拦截和验证用户身份,如图13 (b)所示。安全服务代理拦截来自客户端的所有请求,确定请求服务,然后执行服务要求的安全策略,并将请求从入站协议转换为目标服务要求的协议,最后将请求转发给目标服务。在返回路径上,安全服务代理将结果从服务使用的协议和格式转换为客户要求的协议和格式。它也可以保留客户会话中首次请求创建的安全上下文,供以后的请求使用。


图13 单点登录的2种方式

在UNIT系统中采用Web拦截的方式实现单点登录,采用这种方式可以降低部署成本,简化网络的部署复杂度。在UNIT系统中,登录过程如图14所示。

当用户访问应用系统时,假设其之前没有登录过,则系统将进行如下的身份认证流程。


图14 单点登录认证过程

(1)用户访问目标应用系统,Web拦截器将截获用户的访问请求,首先,拦截器检查被请求的URL是否在无需保护的列表中。如果是则请求被拦截器放行,拦截器不再进行用户身份验证流程,用户访问正常。

(2)如果请求的资源需要身份认证和保护,则Web拦截器将检查请求中是否包含有效的Cookie,若存在 Cookie,拦截器通过与统一认证服务器建立的 SSL 通道向认证服务器验证Cookie是否有效。如果请求有效,则拦截器通过用户的访问请求。

(3)如果请求中没有携带Cookie 或者Cookie 存在但无效,拦截器则将用户的请求重定向到认证服务器的登录界面,要求用户按照系统要求进行常规登录和身份验证。

(4)认证服务器验证用户的登录请求,确认其合法后,将为用户生成一个访问票据,该票据存放在用户的Cookie中。浏览器将保存Cookie值。用户的请求同时被重定向到开始请求的资源地址。

(5)用户携带有效的Cookie 向应用系统发起访问请求,此时拦截器重复第(2)个步骤,确定用户的身份后放行访问请求。

当用户在第一次登录后,Cookie被保留在本地一段时间,因此在有效期内,用户访问该企业的其他应用系统时,只需提交有效的Cookie值给Web拦截器进行验证,无需再次登录即可直接访问资源。

在这个过程中,用户、应用系统与应用服务器之间采用SSL进行通信,使敌手截获和窃取有效信息的可能性十分小。一旦用户通过系统的验证后,可以获得包含票据、用户信息以及与用户访问环境相关参数的有效Cookie。这个Cookie 数据是在SSL通道中传递的,因此 Cookie 被截获的可能性十分低。由于Cookie内容也是被加密的,敌手截获Cookie也无法与应用服务器建立安全访问通道。因此,整个身份认证过程是可靠安全的。

九、数字证书应用案例

在传统的企业自有的网络中,企业中的各个分支机构及其客户是通过专用的线路连接的,即企业的员工之间、企业与其客户之间使用专门的网络设备相互连接在一起。随着Internet的应用以及电子商务的不断发展,企业员工移动办公的现象越来越普遍,企业的业务分支机构及其客户的分布越来越广泛。传统的网络连接的方式越来越无法适应此种商务模式。因此,越来越多的企业使用基于Internet的办公系统,如图15所示。


图15 基于Internet的企业办公网络

在此环境下,企业面临着多种威胁,如企业的员工通过Internet下载或上传企业敏感的信息,信息未经过加密,被别人窃听;如入侵者试图不经过授权来访问企业的敏感的信息;如病毒、间谍软件等不健康的软件试图侵入企业内部的主机,这些侵入可能是通过一个被信任用户的一些日常的通信行为,如打开一个E-mail的附件或者下载一个文件。

面对这些威胁,企业需要建立全面的网络安全管理体系,具体包括:
(1)企业需制定网络的使用者及其访问的信息资源的安全方针,即这个用户或者组用户可以对哪些信息资源进行读、写、执行的操作;
(2)企业需制定网络的使用者所传输的信息的安全方针,即哪些信息需要加密、哪些信息需要防篡改、哪些信息需要防止被否认;
(3)企业需制定主机的安全方针,即在主机上安装哪些操作系统、入侵检测系统、反病毒系统、应用系统、数据库系统等;
(4)企业还需制定审计的方针,即定期审计网络的使用者及所访问的资源的审计记录、主机的审计记录以及应用系统的使用审计记录等,以便审计和跟踪安全事件的发生、运行及结果。

由此可见,不可否认的强认证系统和对信息的保护是满足以上需求的基本条件,使用基于智能密码钥匙的数字证书认证系统可以实现用户登录安全认证、传输数据的机密性保护、完整性检查和抗抵赖性。某保险公司的安全办公系统充分尊重所面临的这些风险,采用PKI技术作为保障公司信息安全的方案,并采用某型智能密码钥匙作为保存和应用RSA密钥对和证书的基础设备。在安全办公系统中,智能密码钥匙用于Windows域登录、支持SSL VPN客户端、支持Office Word文档签章系统。

某保险公司的安全办公系统由公文办公系统、证书认证系统、VPN服务器、VPN客户端、智能密码钥匙(含PKI支撑工具包)组成。公司总部及各分支机构的员工每人持有一把智能密码钥匙,其中保存着本人的X.509数字证书及其相关联的私钥。私钥被物理保护在智能密码钥匙中,不能够被他人窃取和修改。员工使用智能密码钥匙通过SSL VPN客户端登录安全办公系统、安全认证系统验证员工的签名来确认员工的身份,并在员工之间建立起安全的数据传输通道,以确保所传输数据的机密性和完整性,使处理公文、报表等日常的工作能够在安全的环境下进行,企业的敏感信息得到了很好的保护。

发布公文时,发布者使用所持有的智能密码钥匙对公文签名,并将签名隐藏在签章图片中,验证者取得持有者的证书,就可以验证此签名了。由于签名是利用发布者持有的私钥对公文的摘要加密的结果,而发布者是该私钥的唯一持有者,所以不能够否认他对公文的任何改动。另外,通过验证公文的摘要可判断公文是否完整。

下载公文时,服务器得到下载者的证书,使用证书中的公钥将加密了公文的密钥加密,并发送给下载者。由于下载者是对应私钥的唯一持有者,只有下载者能够解密并得到这个用来加密公文的密钥,从而解密得到公文的明文。同样地,上传公文时,先得到服务器的证书,用证书中的公钥将加密了公文的密钥加密,并发送给服务器。由于服务器是对应私钥的唯一的持有者,只有持有者能够解密并得到这个用来加密公文的密钥,从而可以解密公文。

登录办公系统时,用户利用所持有的智能密码钥匙对办公系统所产生的随机数签名,办公系统得到这个签名和持有者的证书后,如果验证签名和证书都合法,由于持有者是私钥的唯一占有者,就能够确认持有者的身份信息,并为其授权。

数字证书以及智能密码钥匙的应用,是保障信息安全和访问控制的基础,为安全办公系统成功地运转提供坚固的支撑,使办公系统具备良好的安全性,有效地保护了公司的信息资源。



下文转自云水的个人博客,感谢原作者。

认证系统几种方式

认证(authentication)和授权(authorization)是经常一起出现的词汇,它俩用途截然不同,认证解决的是如何确定用户的身份,授权是在认证之后,知道用户身份的前提下,决定一个用户拥有什么权限。认证系统包含两个方面:密码存储方案和认证协议,密码如何存储会限制可供选择的认证协议。

1、密码存储方案

很多人都倾向于使用相同或者类似的密码登录不同服务,因此密码存储方案的核心需求是原始明文密码不能被容易的恢复出来,以免殃及其它服务。可惜实际上不同服务由不同方控制,同一密码用不同存储方案保存,安全性取决于最弱的那个。好的服务采用BCrypt,架不住糟糕的服务用明文保存同一个密码,所以还是需要用户做到一站一密,或者服务自己做多因子认证,至于采用安全性好的密码存储方案,这是对一个认证系统的基本要求。

实际工程实现中,密码如何存储经历很多变迁,可惜的是业界并不总是能吸取教训的,2002 年发布的 Mac OS X 10.2 使用的密码加密算法跟 1979 年 Unix第七版的算法是一样的,而且没有采用类似 /etc/shadow 的机制,这个机制是 UNIX 在 1987 年引入的,到了 Mac OS X 10.3 的时候才更改了算法,引入了 shadow 机制,但却没有使用 salt。大公司尚且如此马虎,何况互联网界的中小公司了,时至今日,肯定有一小撮公司使用明文存储密码,一大撮公司用通用摘要算法或者不用 salt,肯定有好大一批公司把用户详细信息跟密码存储在一起,web server 运行的账户 www 或者 nobody能读取所有密码。

理想的做法是把用户信息(用户名到手机号、邮箱、性别等的映射)和认证信息(用户名到密码的映射)分开存放到不同系统里,尤其是跟业务系统分开,因为业务系统涉及到繁杂的业务逻辑,出问题的概率最大。

Salt 的作用是避免词典攻击,所谓词典就是预先算好的摘要值到密码的映射表,大家的密码一般比较短,所以这个表文件可以不大但覆盖巨量密码,有了 salt 后,这个映射就成了 password + salt -> hash,变相的提升了密码长度,只要不同认证系统的 salt 不一样,就没法查表反推原始密码了。看起来有了 salt 后就相当安全了,但其实没有解决暴力破解问题,如果摘要算法是MD5并且密码长度只有六个字符时,暴力破解一个密码只需要一分钟,这就是为什么会有人设计专门针对密码的哈希算法。

1.1 明文
存储明文密码对认证协议的限制是最宽泛的,但此种方案显然是无法满足上面说的核心需求。

1.2 摘要值
早期 UNIX 限制密码长度,采用加密算法如 DES 对原始密码加密保存,现在的认证系统都使用摘要算法,对密码以及一个随机串(称为 salt)应用一个摘要算法,比如 MD5,SHA1,BCrypt,然后保存摘要值以及salt。这种方式是最广泛采用的,但在选择摘要算法时要避免通用摘要算法,因为他们的设计考虑了要快速运算,不利于提高暴力破解的难度,应该选用特别针对密码设计的摘要算法,这类算法被称为key derivation function(KDF),其原理都是通过可配置的迭代次数调节计算量,比通用摘要算法慢几个数量级。

更宽泛点说,依靠生物信息识别用户,也可以认为是把生物信息做了个摘要保存起来,比如指纹,提取指纹特征很容易,但依据这些特征反推指纹出来是很难的,而暴力破解就更难了,单次验证的时间已经在秒甚至分钟级别,只能以偷摸或者暴力的手段直接获取“生物体”本身或其克隆了,这在电影里很常见。

下面的三种 KDF,理论上安全强度 SCrypt > BCrypt > PBKDF2,推荐使用 BCrypt。

1.2.1 PBKDF2
Password-Based Key Derivation Function 2, 由 RSA 实验室提出。这个算法各个主流语言都有实现,应用也非常广泛,比如 WPA/WPA2, WinZip, LastPass, Mac OS X, iOS, Android, Django, Zend, GRUB 2。

PBKDF2 的缺陷是容易被特制的芯片破解,比如使用 ASIC 或者 GPU,所需的电路和 RAM 都很小。

1.2.2 BCrypt
BCrypt 基于 Blowfish 加密算法设计,Blowfish 是密码学界泰山北斗级人物 Bruce Schneier 的大作。跟所有的 KDF 一样,Bcrypt 也是通过调整迭代次数降低运算速度。OpenBSD 率先采用 BCrypt 保存 /etc/shadow 里的密码,PHP 5.5 的 password_hash 函数已经把 BCrypt 作为默认算法,互联网界各路专家推荐,各家公司采用,俨然已经成为密码摘要存储的标准方案

BCrypt 被特制芯片破解的难度稍微大点,所需的电路和 RAM 比 PBKDF2 要多些,但依然是固定的。

1.2.3 SCrypt
SCrypt 特意增大了运算所需内存,因此提高了特制芯片破解的成本,此算法被莱特币(Litecoin) 所使用,但似乎在互联网界并不广泛,可能是大家刚转向 BCrypt,没工夫搭理尚显年轻(2012 年被提出)的SCrypt,或者是采用SCrypt的性价比对互联网企业不合算。

1.3 一次一密算法的参数
在 OTP(One-time password) 算法中,需要在服务端和客户端储存一些参数或者状态,随后认证过程中双方才能使用同样的秘钥函数计算出当前秘钥。

1.4 客户端密码存储
频繁输入密码会让用户很恼火,有两种办法解决:在客户端存储一个 cookie,标记其登录过,并设置过期时间;让客户端保存密码并自动输入。Web 浏览器是典型的保存密码并自动输入的例子,可惜的是伊默认不强制要求设置 master password 以保护那些保存的密码,在设置对话框里就能看到明文密码。

多说两句 cookie。现如今绝大多数网站在用 https 登录后会传给浏览器一个 cookie,记录其 session id 什么的,然后转用 http 协议。这是个非常滑稽的事情,知道 Firesheep 的教训的人依然非常少,很少人意识到这是个巨大的安全漏洞。在有线局域网内,处于同一个 VLAN 的用户是可以抓到这个 VLAN 里的所有数据包的。在采用 WEP 认证的无线网里所有人共用一个秘钥加密网络流量,每个登录成功的人可以破解所有网络流量。在 WPA/WPA2 认证的网络里,虽然每个用户的会话秘钥各不相同,但在 WPA-PSK/WPA2-PSK 模式里攻击者可以比较容易的通过 reauth 攻击得到别人的会话秘钥,被攻击者一般毫不知情(掉线了会自动重连),只有 WPA-Enterprise/WPA2-Enterprise 模式(在无线路由管理界面上一般标记为 WPA/WPA2)没有这个问题,但在家庭网络、咖啡馆、麦当劳这些地方全都用的 PSK 模式,只要一台机器搞鬼或者中木马,整个网络都不安全。一旦窃取到 cookie,那就完全可以扮作被害人操作网站,由于这种攻击是在同一个局域网内,公网 IP 是一样的,服务端也很难区分出来。窃听流量获取 cookie 还是一种被动攻击,如果主动攻击 http 流量,插入或者替换 JS 脚本,被攻击者上当了都难以发觉。总之,在用 WEP、WPA-PSK/WPA2-PSK 认证的地方使用重要服务时,最好保持 https 或者使用 VPN。Firefox 有两个插件可以强制对某些域名使用 https:
https://addons.mozilla.org/en-US/firefox/addon/force-tls/
https://www.eff.org/https-everywhere

可惜,全面默认 https 的风气还没兴盛起来,有的大网站居然都没处理好https。顺带了解了下 WPA 的安全性,居然发现 WPS 有重大漏洞,各位看客赶紧检查自己的无线路由。

也有专门的软件保存密码,有些还能自动输入密码到其它软件。LastPass 应该是最有名的了,但把密码放在它的服务器上总是有点不大放心,也曾爆过安全丑闻。类似功能的开源替代品很多,密码被加密后放在本地,虽然迁移不方便,但终归是在自己手里:
KeePass: http://keepass.info,1.x 版只能用于 Windows 系统, 2.x 版本使用 Mono 编写,支持 Windows/Linux/MacOS X,手机上也有它的各种移植、兼容版本:http://keepass.info/download.html
KeeFox: http://keefox.org/,Firefox扩展,连接 Firefox 和 KeePass
KeePassX: https://www.keepassx.org/, KeePass 1.x 的 Linux 移植版,使用 Qt 库编写,支持 Windows/Linux/MacOS X
KWallet: http://utils.kde.org/projects/kwalletmanager/, KDE 桌面环境的密码管理器
Seahorse: http://www.gnome.org/projects/seahorse, Gnome 桌面环境的密码管理器
Mac OS X keychain: Mac OS X 自带的密码管理器
VIM:VIM 编辑器的 -x 选项可以用来创建加密文件,一旦加密后下次 VIM 打开时会自动识别出来是加密的文件并询问密码。使用这个特性时记得设置 encryptmethod 选项为 blowfish。一直用这个,查找、编辑都很顺手,VIM 做文本操作就是快捷。

2、认证协议

用户注册时选择密码并被服务端保存,随后用户访问这个服务时就要经过认证协议。密码如何存储是服务内部的问题,除非服务被攻破,存储的密码泄露,否则还是不大容易出问题的,而认证协议解决的是在网络两头双方的信息交换,这就太容易出问题了,所以出现繁多的认证协议也就不足为怪。

2.1 双方认证和三方认证
从认证涉及的各方来看,认证协议分为双方认证协议,客户端和服务端,这是最常见的,还有三方认证协议,除了客户端和服务端还引入了一个双方都信任的第三方,比如 Kerberos, CAS(Central Authentication Service), OpenID。下面只看双方认证协议,这也是三方认证的基础。

2.2 单因子认证和多因子认证
双方认证按照认证时提供的凭证个数分为单因子认证(SFA, single-factor authentication)和多因子认证(MFA, multi-factor authentication),而多因子认证里以双因子认证最为常见。

所谓多因子,指认证时需要提供如下凭证:
knowledge factor (something only the user knows),比如密码,某个秘密问题的答案,某个特定模式比如Android上锁屏解锁时的特定滑动序列。
possession factor (something only the user has),比如银行卡, RSA SecurID, 各种银行提供的电子令牌,YubiKey,以及人手一部的手机,各种认证系统往手机发送认证码就是假定了持有手机的人是目标用户。
inherence factor (something only the user is),比如指纹,视网膜,语音。

也有人提第四个因子,somebody you know。

单因子认证一般只需要提供第一个因子(也有只需要第二个因子的,譬如通过目测护照识别身份),双因子一般是提供第一个和第二个因子。多因子认证并不是绝对安全,只是增加被破解的难度。注意有一些认证系统看起来像是双因子认证,其实是单因子认证,比如登录时除了密码,还要回答一个秘密问题,或者可以通过紧急邮箱找回密码,这种做法通过让用户提供多个knowledge factors提高破解难度。

在网上登录绝大部分情况下都是单因子认证,一个密码了事。使用网上银行或者 ATM 机是典型的双因子认证,除了密码之外还要提供电子令牌上的数字或者银行卡,双因子认证方案里几乎不可能被完全不相关的黑客拿到两个因子。

双因子认证很容易在实现时引入漏洞:丢失密码后使用手机发短信即可重置密码(要求额外提供身份证号是不保险的,身份证号并不是保密信息),或者手机上的应用长期缓存第一个因子,只需要提供第二个因子。在安全和方便之间总是难以皆大欢喜。

2.3 互相认证 (mutual authentication)
关于认证还有另外一个问题,大家都明白客户端需要向服务端证明自己身份,很多人可能忽视了服务端向客户端证明自己身份的必要性,这点一旦点出,大家自然明白,好比影视里俩同志接头要互报口令。这也是为什么稍微正经的认证系统登录时需要用 SSL/TLS 的原因之一(另一个重要原因是加密通讯避免用户密码在传输时被窃听),利用 SSL/TLS 客户端检查服务端的 X509 证书。

2.4 协议
具体的认证协议五花八门,可以一刀切分为两类:需要向对方发送密码的,不管是固定密码还是一次一密;不需要向对方发送密码的。

2.4.1 需要向对方发送密码的认证协议
这种协议都需要 SSL/TLS 之类的协议护驾,否则毫无安全可言。

2.4.1.1 HTTP Basic, SMTP PLAIN, SMTP LOGIN
把用户名、明文密码或者BASE64编码的密码发送给服务端。这个是最容易实现的,在 HTML 登录表单里也很好做,服务端可以拿密码跟明文密码比对(不推荐),或者拿提供的密码与 salt 做摘要再跟期望的摘要值比较。

2.4.2 不需要向对方发送密码的认证协议
2.4.2.1 CRAM-MD5
Challenge Response Authentication Mechansim, 所谓的 challenge 就是服务端发给客户端一个随机字符串,客户端需要用密码或者密码的摘要值对其进行 HMAC-MD5 运算,然后把结果发送给服务端,服务端对随机串做相同运算并比对结果。

此协议只是客户端向服务端认证,没有服务端向客户端认证,因此一般需要 SSL/TLS 护驾,让客户端验证服务端证书。具体实现时那个 challenge 往往有比较固定的模式,没有 SSL/TLS 信道加密的话,通讯数据包被窃听后易受词典攻击。

在服务端,密码要么是存为明文,要么是存为 MD5 摘要值或者中间运算结果,一是容易被暴力破解,二是存储的值在 CRAM-MD5 认证协议里跟密码等价,所以拿到这个摘要值其实就是获得了此用户的权限。

2.4.2.2 DIGEST-MD5
相比 CRAM-MD5,在认证过程中允许客户端提供一个随机串添加在服务器给定的随机串上,因此避免了恶意的服务端做选择明文攻击(CRAM-MD5 中对选定明文,客户端返回的摘要值是确定的,因此可以被词典攻击)。

DIGEST-MD5 支持互相认证,但协议本身选项比较多,容易实现不当,互操作性比较差。虽然攻击难度比 CRAM-MD5 大,但一般也需要用 SSL/TLS 保护信道以免窃听。

跟 CRAM-MD5 一样,密码是 MD5 摘要,而且在认证协议里等价于密码,因此在服务端存储的密码是相当不安全的。

2.4.2.3 SCRAM (Salted Challenge Response Authentication Mechanism)
SCRAM 是一族算法,最常见的是 SCRAM-SHA1,设计用来替换 DIGEST-MD5。 SCRAM 比 DIGEST-MD5 更安全也更容易实现,XMPP 把 SCRAM 列为必须支持的认证协议。虽然 SCRAM 规定 SHA1 为必须支持的摘要算法,但 SCRAM 并不限制摘要算法,可以使用 IANA 规定的任何算法

SCRAM 认证是互相认证。存储在服务端的 StoredKey 是 PBKDF2 摘要算法的结果的再次摘要,在 SCRAM 中不是 password 的等价物,即使泄露也不能伪装用户,但存储在服务端的 ServerKey 一旦泄露,攻击者可以伪装服务端。

SCRAM 需要搭配 channel binding 以避免中间人攻击,可以用 SSHv2 和 TLS。所谓通道绑定就是应用层的认证协议利用传输层的加密协议,确认在应用层认证的双方确实是互相通信的双方,避免中间人攻击,注意这里的通道绑定是需要两层协议的具体实现互相支持的,比如上层协议要获取 SSHv2 的 session ID 或者 TLS 里的握手报文内容(tls-unique binding)、X509 证书 (tls-server-end-point binding) 参与认证过程,举例来说,在 TLS 上做通道绑定的 SCRAM-SHA-1 增强版叫 SCRAM-SHA-1-PLUS, 其实现需要 OpenSSL 或者 GnuTLS 库提供获取握手报文内容、X509 证书的 API。

2.4.2.4 SRP (Secure Remote Password protocol)
与 Kerberos 和 SSL X509 不同,SRP 并不依赖第三方的受信秘钥服务或者证书分发机构,SRP 使用共享密码做互相认证。SRP 有大量优良特性:
容许弱密码,攻击者必需跟服务端或者用户端交互才能暴力破解
服务端存储的 salted password 不是密码的等价物,而是类似于公钥;
认证过程不需要传输层加密
认证过程可以生成一个会话秘钥

参考:
http://srp.stanford.edu/
http://en.wikipedia.org/wiki/Secure_Remote_Password_protocol

OpenSSL >= 1.0.1 以及 Apache 2.5 mod_ssl, mod_gnutls 支持 TLS-SRP:
https://issues.apache.org/bugzilla/show_bug.cgi?id=51075
http://sqs.me/security/tls-srp.html(这哥们是 sourcegraph founder…)

但是很不幸 Redhat 为了避免可能的专利纠纷删除了 Fedora、RHEL 中 openssl 软件包里的 srp 代码:
http://tiebing.blogspot.tw/2013/09/tls-psk-tls-srp-and-tls-jpake.html
http://pkgs.fedoraproject.org/cgit/openssl.git/tree/hobble-openssl?id=291d8a35f7cebdaf8d131f036b6dfa60fd3e543b;id2=HEAD

2.4.2.5 AKA
Authentication and Key Agreement,用于 3G 网络中,提供互相认证以及加密通道。

2.4.2.6 EAP
Extensible Authentication Protocol,EAP 是一个认证框架,常用于无线网以及点对点网络中。具体的认证方法称为 EAP method,目前定义了大约四十种。
EAP-TLS: 使用 client & server X509 certificates互相认证,并用TLS加密信道
EAP-POTP: 使用 OTP token 做双因子认证
EAP-PSK: 使用 pre-shared key 做互相认证,认证成功后信道被加密
EAP-PWD: 从一系列共享密码中挑选一个做认证,被 Android 4.0, FreeRADIUS, Radiator 支持
EAP-IKEv2
EAP-FAST
EAP-AKA
PEAP: 为 EAP 提供加密保护

2.4.2.7 RADIUS
基于 UDP 协议。在使用 WPA-Enterprise/WPA2-Enterprise 无线网认证方式的地方就需要 RADIUS 服务。

2.4.2.8 TACACS+
Cisco 开发,基于 TCP 协议,提供 authentication,authorization,accounting.
http://my.safaribooksonline.com/book/networking/network-management/1587052113/access-control/ch03lev1sec1
http://www.openwall.com/articles/TACACS+-Protocol-Security

2.4.2.9 Diameter
代替 RADIUS,提供 authentication,authoriazation,accounting。

2.4.3 双因子认证
以前双因子认证还是个高级货,只用在网上银行以及大型企业 IT 系统的登录系统里,在 Google 推出双因子认证后, Internet 巨头们纷纷支持,加上智能机普及,双因子认证算是飞入寻常百姓家了。

上面提到的SRP、SCRAM,看起来是很安全了,但是总架不住客户端中了木马导致密码泄露,或者密码比较二被人猜出来,或者一个密码打天下忽然惊闻常去的某网站居然是明文存储密码,等等等等,所以牵涉到用户深度隐私或者钱财的服务必须自觉的支持双因子认证。

一般双因子认证使用这两个因子: knowledge factor,基本都是指密码了, possession factor,电子令牌上或者手机上的 Google authenticator 应用显示的认证码,或者是服务端通过短信发到手机上的认证码,这个认证码就是个 one-time password,其生成算法是有业界标准的,并不是个简单的随机数。

Wikipedia 上对 OTP 的讲解很清楚:
http://en.wikipedia.org/wiki/One-time_password
http://en.wikipedia.org/wiki/Google_Authenticator

简单来说,TOTP 就是双方共享一个种子,用一个函数对这个种子以及时间原点到当前逝去的分钟数或者 30s 数目求值,由于种子和时间双方都一致,所以自然解决了认证码的过期问题,以及跟用户对应的问题。这个算法需要客户端和服务端的时间偏移不能太大,TOTP 的 RFC 提到如何容忍稍许的时间不同步,根据用户的输入记录时钟偏移,比如用户连续三次输入上一分钟的认证码,那么服务端就知道用户的时钟慢了一分钟。

HOTP 是双方定一个种子数字,用同一个摘要函数这个种子求值,对结果再次算摘要值,如此反复,由于摘要函数的特性,很难从下一个值推算出上一个值,所以把这些值倒过来就是一个密码表了,每次用下一个密码。

TOTP 比 HOTP 用的更广泛,因为 HOTP 每次使用时都有一个当前状态需要记录,使用上不大方便,而 TOTP 只需要种子数字以及时间同步,另一个 HOTP 的问题是一旦用户不小心泄露了后面的密码,那么这个密码之前的密码都泄露了,通过对后面的密码做摘要即可得到前面的密码。

明白原理后就很容易理解 OTP 是怎么用的了:

起始种子的生成
对硬件形式的电子令牌,生产时会设置好种子到硬件里并备案,管理员购买后会把种子数字输入到 OTP server 里。
对手机上的 OTP 软件,服务端可以发短信、语音到用户,或者网站上生成种子数字的 QR code,用户拿手机扫描出来,然后这个种子被输入到 OTP 软件里;
服务端也可以不把种子发给用户,只是让用户注册手机号,每次用户要登录时,用户点击网页上的获取验证码按钮,服务端就会把当前的认证码通过短信发送到用户的手机上。这种方式安全点,不用担心用户方泄漏了种子数字;
在生成种子的时候,服务端还可以生成一系列的 backup codes,这些数字等价于认证码,用完一个即作废一个。backup codes 是需要用户保存好的,比如打印出来,backup codes 的目的是用户在丢失手机后可以用 backup code 登录。

 
认证码的使用:电子令牌或者手机上的 OTP 软件会显示当前的认证码,用户在登录服务时需要输入用户名、密码、认证码。注意得到认证码的过程是本地算出来的,不需要联系服务器。

Google 的认证系统还有个高级功能,可以为一个账户生成多个副密码,这些密码不需要双因子认证,这个功能是为了给第三方不支持双因子认证的应用访问 Google 服务。

双因子认证提高了认证系统的安全性,但并不意味着认证过程绝对安全,一旦用户密码和某次认证码泄露(比如通过键盘钩子记录按键,然后切断用户和服务端连接),攻击者可以立马登录然后修改密码重新绑定手机重新生成种子,当然这么搞会被用户发觉。也可以隐蔽点,如果攻击者和用户在同一个内网里,攻击者和用户先后登录,并且Web浏览器指纹一样,服务端是没法区分的。

Google authenticator 官方自称 twp-step authentication 而非 two-factor authentication,因为有人诟病它的安全性。传统意义上的 possession factor 是很难复制的,要么拥有要么没有,比如 RSA SecurID 就是抗篡改的(tamper-resistant ),而 Google authenticator 可以同时在多个设备上运行,只要把种子数字从手机里复制出来,这破坏了“something only the user has”的要求。但总之这种 soft token 还是聊胜于无,穷人的福利。

2.4.4 CAPTCHA
CAPTCHA 是 Completely Automated Public Turing test to tell Computers and Humans Apart 的缩写。为了避免脚本自动注册、登录,在注册或者登录表单里添加一个输入框以及小图片,图片上显示一些扭曲的文字,需要用户肉眼识别出来并填入那个输入框里。有的 CAPTCHA 也提供语音输出。

原理很简单,实际应用中也很常见,但做好并不容易,需要挖空心思让机器图形识别困难,但对人肉识别又比较容易,看起来很凌乱的图片,未必难于被机器识别。顺带八卦一下,某些网站的 CAPTCHA 做成了一个广告图片,要求输入广告里某个字眼,做法相当高明,用户不得不看广告。

3、无责任推荐

依优先级顺序,排在前面的优先级高。

3.1 Kerberos/SPNEGO, OpenID
Intranet 使用 Kerberos 和 SPNEGO 做 single sign-on,这个选择已然定论,支持这些协议的操作系统和应用软件都非常广泛。

Internet 使用 OpenID,不用自己操心认证的事情了。但用 OpenID 也是有些烦人的因素了,自己网站的用户登录状况被第三方知道多少是有点让人不爽的事情。对认证的安全把握也完全没有,我就从来不敢在手机上的非 Google 应用里输入 GMail 账号信息,谁知道密码是送给李逵还是李鬼了,界面上也没有什么 OpenID seal 可供识别,在浏览器上还稍微放心点,毕竟浏览器是个相对安全的中立方(排除个别别有用心的浏览器)。

估计大家也是这么想的,所以虽然 OpenID 想法很好,但大家都把它当做锦上添花的特性,不会作为主要的认证方式。

3.2 TLS X509 server certificate + SRP or TLS-SRP
SRP 用于认证本身并不需要 SSL/TLS 保护,但实际应用中需要登录往往意味着需要加密随后的通信,TLS-SRP 是 TLS 协议对 SRP 的直接支持。在 TLS 协议中涉及到四类密码学算法:
认证:互相识别对方身份,可以用 X509 证书(涉及 RSA or DSA), PSK(pre-shared key), SRP,其中 SRP 可以搭配 RSA、DSA 混用增强安全性;
秘钥交换:在不可信通道上交换一个共享的对称加密秘钥,用于随后加密连接,可以用 RSA, SRP, DH, ECDH。
加密算法:加密连接,可以用 3DES, AES 等;
摘要算法:在认证和秘钥交换过程会频繁用到摘要算法,比如 MD5, SHA1;

可以看出 SSL/TLS 协议并不一定需要 x509 证书,可惜所有 Web 浏览器只支持 X509 证书方式的认证,并且对客户端的 x509 证书认证操作比较麻烦,需要用户自己在浏览器设置里导入客户端自己的证书,所以为了应付 Web 浏览器,还是需要结合 TLS X509 server cert 做服务端认证然后加密连接,然后再用 HTML 表单以及 JavaScript 做 SRP 认证(这一步不依赖加密连接),如果是本地应用,可以直接上 TLS-SRP。

TLS-SRP 要求 OpenSSL >= 1.0.1 或者 GnuTLS。 OpenSSL 1.0.1 在 2012 年 3 月 14 日发布。

SRP 在服务端保存的是 verifier,而非 password 或者 password 的等价物,verifier 类似公钥认证里的公钥,所以泄露了也太大问题。

3.3 TLS + SCRAM
使用带有 TLS channel binding 的 SCRAM-SHA-1-PLUS。

3.4 TLS X509 server certificate + PLAIN
实现简单,理解容易,业界最广泛使用的方案。用 x509 证书验证服务端,然后在加密连接上传输密码或者其摘要值给服务端以验证客户端。密码存储使用 BCrypt。

使用 TLS 的注意事项:
使用 OpenSSL >= 1.0.0 的 ECDHE 特性获得 perfect forward secrecy 并且保持高性能。
native client 使用 TLS >= 1.1。
对浏览器使用 SSL >= 3.0 (包含了 TLS 1.0,虽然有问题但是老版浏览器不支持 TLS >= 1.1)。
禁用 TLS compression 和 HTTP compression。
TLS 秘钥交换算法选择优先次序:ECDH > DH > RSA(不支持 perfect forward secrecy) > ECDSA(不是所有客户端都支持)。
让 server 端决定 cipher 优先级顺序(Apache: SSLHonorCipherOrder On, Apache TrafficServer: proxy.config.ssl.server.honor_cipher_order 1),而非默认的让 client 决定。
禁止 TLS client 发起的 renegotiation,对于长连接,server 应在一小时之内发起 renegotiation,短连接应禁止 renegotiation。
Abbreviated handshake(session ID or session ticket extension)有效时间不超过两小时。
优先使用 AES 加密算法,以利用 AESNI 硬件加速。

如果服务端是一个集群,那么 TLS session ID 需要搭配 memcached 做共享的 session cache,而 session ticket extension 需要集群所有机器使用同样的ticket key。

这个方案有两个问题,TLS 证书验证由于用户可能盲目信任未知证书而导致中间人攻击;有可能失误会导致密码被明文传输,譬如客户端逻辑出错没有启用 TLS 连接,譬如登录页面没配置成 https only。

4、实现参考

认证协议是个理解起来伤脑筋,要想实现无误也很费神的事情,有人就构建了许多框架或者 API 来容纳各种认证协议:GSSAPI(Generic Security Services Application Programming Interface),SASL(Simple Authentication and Security Layer), SSPI(Security Support Provider Interface),其中应用最广的当属 SASL,众多网络协议以及 Linux 下无数应用都支持 SASL,不过最遗憾的是 HTTP 协议以及众多 web 浏览器不支持它。


SASL 主流实现有四个:
Cyrus SASL: http://cyrusimap.web.cmu.edu/
GNU SASL: http://www.gnu.org/software/gsasl/
Dovecot SASL: http://wiki2.dovecot.org/Sasl
Java SASL: http://docs.oracle.com/javase/7/docs/technotes/guides/security/sasl/sasl-refguide.html

这些 SASL 实现可以从文件、OpenLDAP、关系数据库读取密码信息并进行验证,也能更改密码,列举用户名,在实现认证系统时最好基于某个 SASL 实现。

4.1 TLS X509 server certificate + SRP or TLS-SRP
单纯的 SRP 实现在 wikipedia 页面上列了很多,目前只有 Cyrus-SASL 支持 SRP。 TLS-SRP 需要 OpenSSL >= 1.0.1 或者 GnuTLS 支持。注意 Fedora、RHEL 官方的 openssl、gnutls 软件包剔除了 SRP 相关代码以避免潜在的专利纠纷。

目前没有 Web 浏览器直接支持 SRP,需要先用 TLS x509 server cert 建立 https 连接,然后用 HTML 表单以及 JavaScript 做 SRP 认证。虽然这个 x509 server cert 不用于认证,但还是需要正规 CA 签发的证书,以免中间人攻击替换掉 HTML 表单以及 JavaScript 从而导致明文密码泄露。

非 Web 浏览器场合,可以直接上 TLS-SRP,不需要 X509 证书。下面是分别用 OpenSSL 和 GnuTLS 演示 TLS-SRP。

4.1.1 OpenSSL
$ touch srpvfile.txt
$ openssl srp -srpvfile srpvfile.txt -userinfo "my test user" -add testuser
$ openssl s_server -nocert -cipher SRP -srpvfile srpvfile.txt -accept 4430
$ openssl s_client -srpuser testuser -cipher SRP -connect localhost:4430

4.1.2 GnuTLS
http://gnutls.org/manual/gnutls.html#Echo-server-with-SRP-authentication

$ srptool --create-conf srppasswd.conf
$ srptool --passwd-conf srppasswd.conf --passwd srppasswd.txt -u testuser
$ gnutls-serv -p 4430 --http --srppasswdconf srppasswd.conf --srppasswd srppasswd.txt --priority NORMAL:-KX-ALL:+SRP:+SRP-DSS:+SRP-RSA
$ gnutls-cli -p 4430 localhost --srpusername testuser --srppasswd 123456 --priority NORMAL:-KX-ALL:+SRP:+SRP-DSS:+SRP-RSA
$ curl --tlsuser testuser --tlspassword 123456 -k https://localhost:4430/

4.2 TLS + SCRAM
SCRAM 的支持程度比 SRP 好点,Dovecot SASL 和 Cyrus SASL 支持 SCRAM-SHA-1,GNU SASL 支持 SCRAM-SHA-1 和 SCRAM-SHA-1-PLUS。

跟 TLS-SRP 一样,没有 Web 浏览器直接支持 SCRAM-SHA-1-PLUS,在 Web 浏览器上也需要 TLS x509 server cert 先建立 https 连接,然后用 HTML 表单以及 JavaScript 做 SCRAM-SHA-1 认证。同样也需要正规 CA 签发的证书以避免 HTML 和 JS 被中间人替换掉。

非 Web 浏览器场合,可以不需要 X509 证书,在 TLS 上启用 aNULL cipher(https://www.openssl.org/docs/apps/ciphers.html) 加 SCRAM-SHA-1-PLUS(tls-unique channel binding)做认证。

4.3 TLS X509 server certificate + PLAIN
需要用正规 CA 签名的 X509 证书,因为这个证书用来验证服务端身份。

各种 SASL 实现都支持 PLAIN 机制,其实自己实现也非常简单了,唯一要注意的是最好把认证服务跟业务逻辑所在服务分开,避免业务逻辑所在服务出篓子被人爬下整个密码库。

认证系统应该启用 https 保护并设置 HSTS 头部

4.4 OTP
OTP 的原理并不复杂,自己实现一个也不难,下面是许多现成的实现供参考。

S/KEY: 古老的 HOTP 类系统:
http://www.ece.northwestern.edu/CSEL/skey/skey_eecs.html,
http://www.fatsquirrel.org/veghead/wot/skey.php

OPIE: S/KEY 的复制品,Debian/Ubuntu 在 2011 年去除了这个软件包,BSD 们还保留着这个古董:
http://www.freebsd.org/doc/handbook/one-time-passwords.html
http://www.linuxjournal.com/content/configuring-one-time-password-authentication-otpw

OTPW: OPIE和S/KEY的替代品,但并不兼容。提供了 PAM module。其原理是生成几百个随机数,前头拼一个 prefix password 然后计算RIPEMD-160 摘要值并按 BASE64 编码显示,用户需要把这个密码表打印出来。这个软件设计思路以及给人的使用体验都很古朴。

Google authenticator,支持 TOTP 和 HOTP,提供了 PAM module,有 Android, iOS, Blackberry 版本的手机应用。Google 后来不提供它新版的源代码了,所以有人做了两个 fork:
https://github.com/kaie/otp-authenticator-android
https://fedorahosted.org/freeotp/

OpenOTP: 商业产品,可以免费供 35 人使用,特性非常丰富的样子。
motp: http://motp.sourceforge.net/, 服务端只是个 shell 脚本,客户端支持许多移动设备,客户端的使用体验很像 RSA SecurID。
Barada: http://barada.sourceforge.net/, HOTP 实现,提供 PAM module 以及 Android app。
LinOTP: http://www.linotp.org/features.html, 特性相当丰富的样子。
multiotp: http://www.multiotp.net/,用纯 PHP 实现了HOTP/TOTP/mOTP 等算法。
python-oath: https://github.com/bdauvergne/python-oath
totp-js: https://github.com/bdauvergne/totp-js
tiqr: https://tiqr.org/ ,支持 QR code scanning,提供服务端、 Android app、iOS app
oath-toolkit: http://www.nongnu.org/oath-toolkit/ ,实现了 TOTP 和 HOTP,提供 PAM module。

没有一个提供 backup code 特性,当然这个不在 OTP 原理里头,只是具体实现时的一个方便用户的特性。实现时可以参考 Google authenticator 和 oath-toolkit。

使用 oath-toolkit 和 Google authenticator 可以验证两者是一致的,Google 返回的 seed 值是 16 个字符的 base32 编码的字符串,实际上 Google authenticator 不要求必需是 16 个字符。

$ oathtool -b --totp 'bkuq 7tya sdbu jlda'  # 字符串的空格被忽略,大小写无关
200157

$ oathtool -b --totp 'bkuq 7tya sdbu jlda' 200157   # 验证
0

将那串 base32 编码字符串输入 Google authenticator 里,可以验证它的结果跟 oathtool 生成的认证码确实是一致的。Google authenticator 可以用于 Google 之外的服务。


5、Token多平台身份认证架构设计思路

5.1 概述

在存在账号体系的信息系统中,对身份的鉴定是非常重要的事情。随着移动互联网时代到来,客户端的类型越来越多, 逐渐出现了 一个服务器,N个客户端的格局 。不同的客户端产生了不同的用户使用场景,这些场景:


有不同的环境安全威胁
不同的会话生存周期
不同的用户权限控制体系
不同级别的接口调用方式

综上所述,它们的身份认证方式也存在一定的区别,本节将使用一定的篇幅对这些场景进行一些分析和梳理工作。

5.2 使用场景

下面是一些在IT服务中常见的一些使用场景:
用户在web浏览器端登录系统,使用系统服务
用户在手机端Android/iOS登陆系统,使用系统服务
用户使用开放接口登录系统,调用系统服务
用户在PC处理登录状态时通过手机扫码授权手机登录使用得比较少
用户在手机处理登录状态进通过手机扫码授权PC进行登录比较常见

通过对场景的细分得到如下不同的认证token类别:

5.2.1 原始账号密码类别
用户名和密码
API应用ID/KEY

5.2.2 会话ID类别
浏览器端token
移动端token
API应用token

5.2.3 接口调用类别
接口访问token
身份授权类别
PC和移动端相互授权的token

5.2.3 token的类别
不同场景的token进行如下几个维度的对比:
天然属性对比:
1使用成本
本认证方式在使用的时候,造成的不便性。比如:
账号密码需要用户打开页面然后逐个键入
二维码需要用户掏出手机进行扫码操作

2变化成本
本认证方式,token发生变化时,用户需要做出的相应更改的成本:
用户名和密码发生变化时,用户需要额外记忆和重新键入新密码
API应用ID/KEY发生变化时,第三方应用需要重新在代码中修改并部署
授权二维码发生变化时,需要用户重新打开手机应用进行扫码
环境风险
被偷窥的风险
被抓包的风险
被伪造的风险

可调控属性对比:
1使用频率
在网路中传送的频率

2有效时间
此token从创建到终结的生存时间

最终的目标:安全和影响。

安全性和隐私性主要体现在:
token 不容易被窃取和盗用通过对传送频率控制
token 即使被窃取,产生的影响也是可控的通过对有效时间控制

关于隐私及隐私破坏后的后果,有如下的基本结论:
曝光频率高的容易被截获
生存周期长的在被截获后产生的影响更严重和深远

遵守如下原则:
变化成本高的token不要轻易变化
不轻易变化的token要减少曝光频率网络传输次数
曝光频率高的token的生存周期要尽量短

将各类token的固有特点及可控属性进行调控后, 对每个指标进行量化评分1~5分,我们可以得到如下的对比表:



备注:user_name/passwd 和 app_id/app_key 是等价的效果

5.3 token的层级关系

参考上一节的对比表,可以很容易对这些不同用途的token进行分层,主要可以分为4层:
密码层:最传统的用户和系统之间约定的数字身份认证方式
会话层:用户登录后的会话生命周期的会话认证
调用层:用户在会话期间对应用程序接口的调用认证
应用层:用户获取了接口访问调用权限后的一些场景或者身份认证应用

token的分层图如下:



在一个多客户端的信息系统里面,这些token的产生及应用的内在联系如下:
用户输入用户名和用户口令进行一次性认证
在 不同 的终端里面生成拥有 不同 生命周期的会话token
客户端会话token从服务端交换生命周期短但曝光 频繁 的接口访问token
会话token可以生成和刷新延长 access_token 的生存时间
access_token可以生成生存周期最短的用于授权的二维码的token

使用如上的架构有如下的好处:
良好的统一性。可以解决不同平台上认证token的生存周期的归一化问题
良好的解耦性。核心接口调用服务器的认证 access_token可以完成独立的实现和部署
良好的层次性。不同平台的可以有完全不同的用户权限控制系统,这个控制可以在 会话层 中各平台解决掉

5.3.1 账号密码

广义的 账号/密码 有如下的呈现方式:
传统的注册用户名和密码
应用程序的app_id/app_key

它们的特点如下:
1)会有特别的意义
比如:用户自己为了方便记忆,会设置有一定含义的账号和密码。

2)不常修改
账号密码对用户有特别含义,一般没有特殊情况不会愿意修改。而app_id/app_key则会写在应用程序中,修改会意味着重新发布上线的成本。

3)一旦泄露影响深远
正因为不常修改,只要泄露了基本相当于用户的网络身份被泄露,而且只要没被察觉这种身份盗用就会一直存在。所以在认证系统中应该尽量减少传输的机会,避免泄露。

5.3.2 客户端会话token

功能:
充当着session的角色,不同的客户端有不同的生命周期。

使用步骤:用户使用账号密码,换取会话token。

不同的平台的token有不同的特点:
Web平台生存周期短

主要原因:
环境安全性:由于web登录环境一般很可能是公共环境,被他人盗取的风险值较大
输入便捷性:在PC上使用键盘输入会比较便捷

移动端生存周期长

主要原因:
环境安全性:移动端平台是个人用户极其私密的平台,他人接触的机会不大
输入便捷性:在移动端上使用手指在小屏幕上触摸输入体验差,输入成本高

5.3.3 access_token

功能:服务端应用程序api接口访问和调用的凭证。

使用步骤:使用具有较长生命周期的会话token来换取此接口访问token。其曝光频率直接和接口调用频率有关,属于高频使用的凭证。为了照顾到隐私性,尽量减少其生命周期,即使被截取了,也不至于产生严重的后果。

注意:在客户端token之下还加上一个access_token, 主要是为了让具有不同生命周期的客户端token最后在调用api的时候,能够具有统一的认证方式。

5.3.4 pam_token

功能:由已经登录和认证的PC端生成的二维码的原始串号Pc Auth Mobile。

主要步骤如下:
PC上用户已经完成认证,登录了系统
PC端生成一组和此用户相关联的pam_token
PC端将此pam_token的使用链接生成二维码
移动端扫码后,请求服务器,并和用户信息关联
移动端获取refresh_token(长时效的会话)
根据 refresh_token 获取 access_token

完成正常的接口调用工作

备注:生存周期为2分钟,2分钟后过期删除 没有被使用时,每1分钟变一次 被使用后,立刻删除掉,此种认证模式一般不会被使用到。

5.3.5 map_token

功能:由已经登录的移动app来扫码认证PC端系统,并完成PC端系统的登录Mobile Auth Pc。

主要步骤:
移动端完成用户身份的认证登录app
未登录的PC生成匿名的 map_token
移动端扫码后在db中生成 map_token 和用户关联完成签名
db同时针对此用户生成 web_token
PC端一直以 map_token 为参数查找此用户命名的 web_token
PC端根据 web_token 去获取 access_token

后续正常的调用接口调用工作

备注:生存周期为2分钟,2分钟后过期删除没有被使用时,每1分钟变一次 被使用后,立刻删除掉。

5.4 小结与展望

本文所设计的基于token的身份认证系统,主要解决了如下的问题:
token的分类问题
token的隐私性参数设置问题
token的使用场景问题
不同生命周期的token分层转化关系

本文中提到的设计方法,在应用层中可以适用于且不限于如下场景中:
用户登录
有时效的优惠券发放
有时效的邀请码发放
有时效的二维码授权
具有时效 手机/邮件 验证码
多个不同平台调用同一套API接口
多个平台使用同一个身份认证中心

至于更多的使用场景,就需要大家去发掘了。


6、总结