在前面的学习中,我们讨论了访问控制的基础和形式化模型。但访问控制有一个前提:系统必须知道“你是谁”。在决定“你能做什么”之前,系统必须先确认“你是谁”。这个确认身份的过程就是认证(Authentication)。
认证是安全系统的第一道防线,也是最常被攻击的环节。如果攻击者能够绕过认证,或者冒充合法用户,整个访问控制系统就会失效。历史上,许多安全漏洞都源于认证机制的缺陷:弱密码、密码泄露、会话劫持、身份伪造等。

认证失败是大多数安全事件的根源。如果攻击者能够通过认证,他们就获得了系统的信任,可以执行授权范围内的操作。这就是为什么认证机制必须足够强大,能够抵御各种攻击。
认证和授权是两个经常被混淆的概念。认证回答“你是谁”的问题,授权回答“你能做什么”的问题。认证是授权的前提——系统必须先知道你是谁,才能决定你能做什么。但在实际系统中,这两个概念往往交织在一起,使得区分它们变得困难。
理解认证和授权的区别对于设计安全系统至关重要。虽然它们密切相关,但它们是两个不同的安全机制,解决不同的问题。
认证是验证身份的过程。系统需要确认声称是某个用户的人或实体确实是该用户。这通常通过以下方式实现:
认证是一个二元决策:要么认证成功(身份被确认),要么认证失败(身份未被确认)。认证成功后,系统知道“你是谁”,但还不知道“你能做什么”。
授权是授予权限的过程。系统需要决定一个已认证的用户可以执行哪些操作,访问哪些资源。这通常通过访问控制列表、角色、权限等机制实现。
授权不是二元决策,而是多层次的。一个用户可能对某些资源有完全访问权限,对某些资源只有读取权限,对某些资源完全没有权限。授权决策可能基于用户的身份、角色、属性、上下文等因素。
认证是"验证身份",授权是"授予权限"。认证在前,授权在后。没有认证,授权就没有意义,因为你不知道是谁在请求权限。
在实际系统中,认证和授权往往交织在一起,使得区分它们变得困难。比如,一个用户可能通过认证后自动获得某些权限,或者某些操作可能同时需要认证和授权检查。
但理解它们的区别仍然重要。认证机制应该专注于验证身份,授权机制应该专注于授予权限。如果认证和授权混在一起,系统可能难以维护、难以审计、难以扩展。
基于知识的认证是最常见的认证方式。用户需要提供只有他们知道的信息来证明身份,最典型的就是密码(Password)。
密码认证的历史可以追溯到计算机系统的早期。在分时系统中,每个用户需要一个账户和密码来访问系统。密码存储在系统文件中,系统在用户登录时验证密码。
早期的密码系统存在许多安全问题。密码以明文形式存储,任何能够访问密码文件的人都可以看到所有密码。密码传输也是明文的,攻击者可以通过网络监听获取密码。这些问题促使了密码学在认证中的应用。

现代密码系统不应该存储明文密码,而应该存储密码的哈希值。当用户输入密码时,系统计算密码的哈希值,并与存储的哈希值比较。如果匹配,认证成功。
但简单的哈希还不够。如果两个用户使用相同的密码,它们的哈希值也相同,攻击者可以通过比较哈希值来发现使用相同密码的用户。更严重的是,如果攻击者获得了密码文件,他们可以使用彩虹表(Rainbow Table)来快速查找常见密码的哈希值。
密码哈希必须使用盐(Salt)。盐是一个随机值,与密码一起哈希。即使两个用户使用相同的密码,由于盐不同,它们的哈希值也不同。这防止了彩虹表攻击,也防止了通过比较哈希值发现相同密码。
现代密码系统使用专门的密码哈希函数,如bcrypt、scrypt、Argon2等。这些函数不仅使用盐,还故意设计得计算成本高,使得暴力破解攻击变得困难。即使攻击者获得了密码哈希值,也需要花费大量计算资源来破解密码。
密码策略定义了密码的复杂度要求。常见的密码策略包括:
但密码策略往往在安全性和可用性之间产生冲突。过于严格的密码策略可能导致用户难以记住密码,从而采用不安全的行为,如将密码写在纸上,或者使用简单的变体来满足策略要求。
密码策略的目标是提高密码强度,但如果策略过于严格,用户可能采用不安全的行为来应对。平衡安全性和可用性是密码策略设计的关键。
近年来,一些组织开始采用更灵活的密码策略。比如,允许长密码短语(Passphrase)而不是短密码,因为长密码短语可能更容易记住,同时提供足够的熵。或者,使用密码强度检查器(Password Strength Meter)来评估密码强度,而不是强制执行固定的规则。
攻击者使用多种方法来攻击密码系统:
暴力破解(Brute Force):尝试所有可能的密码组合。对于短密码或简单密码,这种方法可能很快成功。但对于长密码或复杂密码,这种方法需要大量时间和计算资源。
字典攻击(Dictionary Attack):使用常见密码列表进行攻击。许多用户使用常见密码,如"password"、"123456"等。攻击者可以使用这些常见密码列表来快速尝试。
彩虹表攻击(Rainbow Table Attack):使用预计算的哈希表来查找密码。如果密码没有使用盐,或者盐是已知的,攻击者可以使用彩虹表来快速查找密码。
社会工程攻击(Social Engineering):通过欺骗用户来获取密码。攻击者可能伪装成系统管理员,要求用户提供密码,或者通过钓鱼邮件引导用户到伪造的登录页面。
密码重用攻击:利用用户在多个系统中使用相同密码的行为。如果攻击者在一个系统中获得了密码,他们可能在其他系统中使用相同的密码。
防御这些攻击需要多层防护:使用强密码策略、使用盐和慢速哈希函数、实施账户锁定机制、监控异常登录行为、使用多因素认证等。
基于拥有物的认证要求用户拥有某个物理对象来证明身份。这个对象可能是智能卡、硬件令牌、USB密钥等。
智能卡(Smart Card)是一种包含集成电路的卡片,可以存储和处理信息。智能卡通常用于身份认证,用户需要插入智能卡并输入PIN码来证明身份。
智能卡的优势是它们难以复制。即使攻击者获得了智能卡,没有PIN码也无法使用。智能卡还可以存储加密密钥,用于数字签名或其他加密操作。
但智能卡也有劣势。用户必须随身携带智能卡,如果丢失或被盗,可能被滥用。智能卡需要读卡器,这增加了部署成本。智能卡也可能被物理攻击,如侧信道攻击、故障注入攻击等。
硬件令牌(Hardware Token)是一种生成一次性密码(One-Time Password,OTP)的设备。用户按下按钮,令牌显示一个临时的密码,用户使用这个密码进行认证。这个密码通常只在短时间内有效(如30秒或60秒),使用后即失效。
硬件令牌的优势是它们生成动态密码,即使攻击者截获了密码,也无法重复使用。令牌通常需要物理访问才能使用,这增加了攻击的难度。
但硬件令牌也有劣势。用户必须随身携带令牌,如果丢失或被盗,可能被滥用。令牌需要电池,可能耗尽。令牌也可能被物理攻击或逆向工程。
USB密钥(USB Key)是一种基于USB接口的硬件认证设备。最著名的是FIDO(Fast IDentity Online)标准,包括U2F(Universal 2nd Factor)和WebAuthn。
FIDO设备使用公钥密码学。设备内部生成密钥对,私钥永远不离开设备。当用户需要认证时,服务器发送一个挑战(Challenge),设备使用私钥签名挑战,服务器使用公钥验证签名。
FIDO设备提供了强大的认证安全性。私钥永远不离开设备,即使服务器被攻破,攻击者也无法获得私钥。这提供了比密码更强的安全性。
FIDO设备的优势包括:抵抗钓鱼攻击(设备会验证服务器身份)、抵抗中间人攻击、私钥不离开设备、支持多种认证方式(指纹、PIN等)。
基于生物特征的认证使用用户的生理或行为特征来验证身份。常见的生物特征包括指纹、虹膜、面部、声音、手写等。
生理特征:基于身体特征的认证,如指纹、虹膜、面部、DNA等。这些特征通常是稳定的,不会随时间显著变化。
行为特征:基于行为模式的认证,如打字节奏、步态、签名等。这些特征可能随时间变化,需要适应。
生物特征认证的优势是它们难以伪造或共享。指纹、虹膜等特征对于每个人都是独特的,攻击者难以复制。用户不需要记住密码或携带令牌,只需要提供生物特征。

生物特征不应该作为唯一的认证因素。它们应该与其他因素(如密码、令牌)结合使用,形成多因素认证。这样即使生物特征被伪造,攻击者仍然需要其他因素。
生物特征系统不应该存储原始生物特征数据,而应该存储生物特征模板(Template)。模板是生物特征的数学表示,即使攻击者获得了模板,也无法重建原始生物特征。
但模板仍然可能被滥用。如果攻击者获得了模板,他们可能使用它来创建伪造的生物特征。这就是为什么生物特征系统必须保护模板,使用加密存储、访问控制等措施。
多因素认证(Multi-Factor Authentication,MFA)结合使用多个认证因素来提高安全性。即使攻击者获得了其中一个因素,他们仍然需要其他因素才能通过认证。
认证因素可以分为三类:
知识因素(Something You Know):只有用户知道的信息,如密码、PIN码、安全问题答案。
拥有因素(Something You Have):只有用户拥有的物理对象,如智能卡、硬件令牌、手机。
存在因素(Something You Are):用户的生物特征,如指纹、虹膜、面部。

多因素认证要求使用来自不同类别的因素。使用密码和PIN码不是多因素认证,因为它们都属于知识因素。使用密码和智能卡才是多因素认证,因为它们来自不同的类别。
多因素认证提供了比单因素认证更强的安全性。即使攻击者获得了密码,他们仍然需要物理令牌或生物特征才能通过认证。这大大降低了账户被攻破的风险。
多因素认证还可以检测账户被盗用。如果攻击者尝试使用正确的密码但错误的第二因素,系统可以检测到异常行为并发出警报。
在实际系统中,认证机制面临各种攻击。理解这些攻击以及如何防御它们,是设计安全认证系统的关键。
认证成功后,系统通常创建一个会话(Session)来维护用户的认证状态。会话管理是认证系统的重要组成部分,但也可能成为攻击目标。
防御这些攻击需要:使用不可预测的会话ID、在认证成功后重新生成会话ID、使用HTTPS保护会话ID传输、实施适当的会话超时、使用安全标志(如HttpOnly、Secure)保护Cookie。
密码重置功能是认证系统的重要组成部分,但也可能成为攻击目标。攻击者可能尝试:
防御这些攻击需要:对所有账户返回相同的消息(无论账户是否存在)、使用安全的渠道传输重置令牌、限制重置令牌的有效期、使用多因素认证进行密码重置。
账户锁定机制可以防止暴力破解攻击。如果用户多次输入错误密码,账户可能被锁定。但这也可能被攻击者利用:
防御这些攻击需要:实施渐进式延迟(随着失败次数增加,延迟时间增加)、使用CAPTCHA来防止自动化攻击、监控异常行为、对锁定的账户返回通用错误消息。
单点登录允许用户使用一个账户访问多个系统。这提高了用户体验,但也增加了安全风险。如果SSO系统被攻破,攻击者可以访问所有关联的系统。
SSO系统必须特别安全,使用强认证机制、加密通信、审计日志等。SSO系统还应该支持细粒度的权限控制,确保用户只能访问授权的系统。
认证是安全系统的第一道防线。它回答“你是谁”的问题,是授权的前提。认证可以通过多种方式实现:基于知识的认证(密码)、基于拥有物的认证(令牌、智能卡)、基于生物特征的认证(指纹、虹膜)。
每种认证方式都有其优势和劣势。密码易于部署但可能被破解,令牌提供更强的安全性但需要额外硬件,生物特征难以伪造但存在隐私问题。多因素认证结合使用多个因素,提供了比单因素认证更强的安全性。
在下一节中,我们将讨论密码学。密码学是许多安全机制的基础,包括密码存储、加密通信、数字签名等。