2FA简介

说是2FA,其实包含了MFA。也就是在登陆过程中采取两种或者两种以上的因素进行身份认证。一般来说我们懂,第一身份认证方式永远是密码。因此第二身份认证方式就不能是密码。而且为了增强安全性,一般2FA还有以下要求。

  1. 2FA的认证系统,和登陆系统,最好不在同一台机器上。因为第二因素认证主要就是为了防止密码被窃取导致用户身份窃取。如果两者可能同时泄漏,那2FA就肯定不合格。
  2. 2FA的认证中,如果采用输入数据方式的,输入的数据最好具备时效性。即两次登陆所传输的数据不同,且上次传输的数据不能用于下次登陆。这主要是为了防止重放攻击。

常见的2FA认证方式

RFC6238

非常流行的验证方式。下载个验证器,例如Aegis(我不大推荐Google Authenticator,那个不开源)。然后扫描一个QR码。验证器和服务器就会共享一个密钥。两者根据时间和密钥能算出一致的验证码(默认6位数)。验证时输入验证码即可认证身份。而由于时间参与运算,因此验证码30秒一换。一般系统会认可当前时间,30秒前,和30秒后的验证码,以免手机存在时间不一致的现象。因此一个验证码最长有效时间1分半,一般有效时间30秒到1分钟。攻击者单次得到验证码后一般无法重复使用。当然,能在半分钟内完成攻击的攻击者RFC6238无法防御。

U2F Key

比较新的验证方式。U2F是一个独立的硬件,一般插入USB,或者用NFC通讯。硬件内有CPU,使用时分两步。

  1. 注册。用户将某个U2F设备绑定到某个系统。此时设备会为这个系统生成一个新的公私钥对,并且把公钥发送给系统。系统要储存这个公钥以备后续验证。
  2. 验证。系统通过公钥验证用户是否持有私钥。这个步骤一般会要求你触摸物理设备以防攻击者趁你插着U2F设备偷偷做验证。

由于整个过程不需要传递私钥,因此私钥可以(理论上)只保存于U2F设备内不可提取。由此来保护U2F不可复制。

有兴趣的可以看一下Yubico的设备实现细节。Yubico并没有存储所有的私钥。它其实使用内置密码,随机数和网站名来哈希生成私钥的。随机数会被丢给网站保存,下次验证时再从网站取回来。由于不传递内置密码,因此即便获得随机数也算不出私钥。而由于有网站名参与生成私钥,因此对每个网站他的私钥都不相同。

物理Token/验证器/动态口令牌

这三个说的都是同一个东西,就是一个物理的令牌卡,里面装着电池。按一下,或者输入密码(准确说是pin),里面会给出验证码。一般一个验证器对应一个网站。你可以认为是一个定制的RFC6238专用设备。其中需要输入密码的形式强度比较高一些。

Token还有个变形是系统会给出挑战码。你需要输入挑战码才能得到验证码。这个形态用起来更加不好用一点。

定制令牌

这种就是类似于招行U盾之类的东西。也是一个独立硬件,插USB口上。初始化会写入证书和私钥,后续私钥无法读取,以此来保护不可复制。一般会用一个密码来保护硬件设备,以防丢失。

定制令牌其实可以视为一个OpenPGP接口的smart card,但一般接口不通用。其安全性和U2F相仿,但是由于没有"摸一下"这个步骤,因而容易被MITM攻击。通俗点说就是有人可以趁你插上设备解密后,偷偷装作是你使用设备。因此定制令牌在不使用的时候都需要拔下。

短信和电话

基于SIM的验证方式。发个验证码或者打个电话给你。输入验证码完成验证。

从抗丢的角度来说,电话验证要比短信弱一点。因为锁屏一般也可以接电话,但是未必能看到短信。但是从系统拦截的角度来说,拦截短信要比拦截电话并识别语音内容要简单的多。

SIM的优点是容易找回。一般你不会用一个一次性的,不和身份绑定的手机卡做验证,对吧。因此不会出现硬件丢失导致系统进不去的问题,了不起补办SIM卡。缺点就是,一,智能手机系统可能拦截验证信息。二,运营商和政府能很容易的拦截验证码。

邮件

SIM卡验证的邮件版本。由于邮件系统先天不加密,所以邮件的安全性是所有系统里最差的。如果看到某个系统把"邮件"列为可选2FA,我建议你干脆关了吧。但是邮件在通知和取证合法性上是最好的。很多网站会在你做了安全操作后给你发邮件通知确认。

很多网站可以通过邮件验证来找回密码。此时邮件就承担了密码等同的功能。这是很危险的,安全性全赖邮件系统不泄漏,而且是发送方邮件系统和接收方邮件系统均不泄漏。因此千万别用小厂邮箱做身份绑定。一方面泄漏风险大,另一方面,万一关门了也够烦的。注意这里不但指邮箱系统不要用小厂的。如果你用自定义域名,域名供应商也要一并考虑。

对于SIM卡和邮件来说,我建议你的"验证系统"和"日常系统"分离。例如手机弄两张SIM卡。日常用一张,验证用一张。邮箱同理。最好验证用的SIM卡和手机都是专用的。这台手机上干脆别装什么其他应用。

专用App/QR扫码辅助登陆

专用App指Okta那种。需要提前登陆。登陆后有个功能,按一下就可以认可后续的登陆。这种系统安全性和RFC6238差不多,秘密的安全性取决于系统和软件。相对于RFC6238,专用App的优点是使用快捷一按就得,缺点是通讯要求网络稳定。

QR码就是不按按钮,通过扫描系统提供的QR码来确认你的身份。专用App一旦能扫码,就能为其他网站提供身份认证,因而可以视作一种SSO系统。在国内,微信就大量被用作这种SSO系统。

上面两者的机制不同,但是效果很类似。

备用码

对所有"丢失后无法找回"的辅助认证系统来说,一定要有备用码的功能,或者你要做好丢失硬件后无法访问系统的准备。备用码是一种预先发给你的代码,在验证硬件丢失的情况下,可以用来重设2FA。当然,由于它有这个效力,因此也可能在丢失的情况下威胁系统安全。千万不要把备用码存放在登陆的电脑上,否则不如放弃2FA。

比较蛋疼的是。备用码发给你的过程,本身就要在登陆系统上完成。因此只能假定你在收到备用码的时刻,电脑并没有被入侵。否则备用码机制会使得2FA失去效用。

很多人喜欢用手机拍照保存备用码。这种情况下记得两点。一,不要开启照片云同步。二,保存数据的手机和验证手机不能是同一台。

安全性分析

我们首先把2FA验证机制分为两类。需要通讯的验证机制和不需要通讯的验证机制。所谓通讯是指2FA的系统和目标系统通讯,不是你的登陆电脑和目标系统通讯。上面的各种方法中,RFC6238,Token,定制令牌和U2F不需要通讯。严格来说备用码也不用,但我们不把它视为一种2FA。

不需要通讯的认证方式

  1. 不需要通讯的验证方式比需要通讯的验证方式更加快捷稳定。例如,相对于手机。在验证码发送服务商忙碌的时候,可能你恨不得砸了手机。不需要通讯的认证方式就没有这个烦恼。
  2. RFC6238,Token,定制令牌和U2F都拥有"秘密"。因而其安全性取决于如何保守这些"秘密"。这方面显然Token,定制令牌和U2F要强于RFC6238。因为后者往往需要一台智能手机作为基础,而手机可能存在各种漏洞导致密码/密钥被窃取。
  3. 在抵抗物理盗窃方面,RFC6238,Token和定制令牌则要强于U2F。U2F上一般都不会配备二次验证装置,常规就是在需要验证时让你摸一下。但是物理盗窃后是无力抵抗的。而前几个一般都会配备二次验证装置。手机可以上锁,Token一般带有pin,定制令牌带有密码。因此丢失后依然可以抵抗盗用。从这个角度说,U2F应当带指纹。但是这样会更贵。
  4. 使用便利性上,RFC6238,Token和定制令牌由于需要二次验证,一定会比U2F难用。
  5. 因此首选推荐U2F和RFC6238。前者便利好用且强抵抗密钥复制,缺点是怕物理窃取。后者抵抗物理盗窃且很多系统都有实现,缺点是秘密的安全性取决于系统和软件。Token和定制令牌的最大缺点是太少有系统配置。一般常见于安全产品和银行产品。

需要通讯的认证方式

  1. 由于邮箱的安全性隐患,因此实践上SIM卡一般比邮箱强一点。但其实是强点有限。因为验证码在运营商那里还是透明的。只是手机运营商一般比邮箱运营商更专业,因而能带来一些实践上的保护作用。
  2. 从法律上讲,手机运营商没有给你任何额外的安全性承诺。如果你的账户依赖于手机或邮箱的安全性,在出问题的情况下无法向这两者索赔。这在银行系统里是很重要的。与之对应的,如果你能证明你的钱被偷是因为银行Token或令牌的缘故,银行是要对你负责的。
  3. 无论是邮箱,SIM卡,还是专用App,都无法保护你对抗政府。
  4. 大部分基于通讯的认证方式优点是天然抗物理盗窃。但与之相对的,你需要对自己的终端负责一点。手机开密码或指纹保护,SIM卡开启pin码。锁屏通知要隐藏内容。手机千万别root。如果笔记本能自动收邮件,那么笔记本本身就要带密码,而且记得勤锁屏。
  5. 强度上来说,专用App和SIM卡很难说。我个人倾向于专用App更强一些。因为专用App的安全性只依赖于你的系统和软件的安全性。SIM卡的安全性不仅依赖于系统和软件,还依赖于运营商系统。但是相对的,专用App的密码安全性就要足够强。

结论

推荐上来说。我首推U2F。使用简单但要注意防止丢失。不支持U2F的,建议采用RFC6238。再次之选择专用App/QR扫码。再次之选择SIM卡。最差选择邮件。