很早之前我的 dnspod 账号被盗过,导致域名被人通过 Api 设置了泛解析,指向了一堆垃圾网站。从那之后我终于痛下决心,把常用的 WEB 服务全部梳理了一遍,使用各不相同的密码(Mac 和 iPhone 上我都买了 1Password,用来生成和管理这些密码)。对于支持两步验证的网站,我一定会启用它。最近,imququ.com 这个我基于 ThinkJS 开发的博客系统,后台登录也启用了两步验证。本文来讨论有关两步验证的话题。
两步验证,对应的英文是 Two-factor Authentication(2FA),有些地方也称之为 Two-step Verification,它跟 OAuth 2.0 没有关系,不要搞混了。从名字可以看出,「两步」是 2FA 的重点,广义的 2FA 是指提供多种方案完成用户权限鉴定。例如某些网站,在验证 完用户名和密码之后,还需要输入手机收到的校验码才能登录成功;某些安全性要求比较高的场景,比如银行网银或者 VPN,会单独提供一个硬件设备辅助完成用户权限认证。这都是 2FA。
我们知道,登录非 HTTPS 网站时,用户名密码都是明文传输,很容易被人截获。即使采用了 HTTPS,如果电脑被装了键盘记录器,或者浏览器被装了不良扩展,密 码还是会被盗。两步验证解决的问题是:即使用户名密码输入正确,还需要输入额外的校验码才能登录;而这个校验码是一次性的,即使在传输过程中被拦截到也不要紧。既然用 户电脑环境并不一定安全,网站需要使用其他途径分发校验码,例如通过短信、电话、硬件设备,才能保证最终的安全。
这个网站列出了哪些网站支持 2FA,哪些不支持,以及各自支持生成校验码的方式。从这个列表中可以看到,大部分国外知名 WEB 服务都支持 2FA。这个列表最后一列,是指用软件实现(Software Implementation)的 2FA。它的工作原理是网站为每个用户生成一个密钥,用户手机需要 安装能根据这个密钥算出校验码的软件,用户通过算好的校验码,在网站上完成额外的验证。这种方案成本低廉,使用方便,得到了大部分网站的支持。
前面说过,2FA 中使用的是一次性密码(One Time Password,OTP),也被称作动态密码。一般 OTP 有两种策略:计次使用和计时使用。计次使用的密码使用过一次就失效;计时使用的密码过一段时间就失效。
HOTP 的全称是 HMAC-based One Time Password,它是基于 HMAC 的一次性密码生成算法。HMAC 的全称是 Hash- based Message Authentication Code,是指密钥相关的哈希运算消息认证码。HMAC 利用 MD5、SHA-1 等哈希算法,针对输入的密钥和消息,输出消息摘要。HOTP 算法中,传入密钥 K 和计数器 C,得到数字校验码。
实际使用 HOTP 中,服务端会给用户生成密钥 K,并约定起始计数器 C。客户端根据 K 和 C 生成校验码,并在用户点击刷新按钮后将计数器加
1,同时更新校验码;而服务端会在每次校验成功后将计数器加
1,这就保证了校验码只能使用一次。但客户端刷新并不通知服务端,很可能出现客户端计数器大于服务端的情况。所以一般的实现里,服务端如果用 PASSWORD = HOTP(K, C)
验证失败,还会尝试
C+1、C+2...,如果匹配上了,就更新服务端的计数器,保证跟客户端步调一致。出于安全考虑,服务端会设置一个最大值,并不会无限制地尝试下去。
HOTP 的优点是可以事先算好一批校验码,用户可以把他们打印出来随身携带逐个使用,用一个划掉一个,达到客户端计数器累加的效果,这样可以完全不依赖于电子设备。HOTP 的缺点是计数器很容易不一致,服务端经常需要通过不断尝试来同步计数器,从而降低了安全性。
TOTP 的全称是 Time-based One-time Password,它是基于时间的一次性密码生成算法。TOTP 算法需要约定一个起始时间戳
T0,以及间隔时间 TS。把当前时间戳 now 减去 T0,用得到的时间差除以 TS 并取整,可以得到整数 TC。根据 PASSWORD = HOTP(K, TC)
就可以得到数字校验码。
TOTP 实际上只是把 HOTP 的递增计数器换成了与当前时间有关的 TS,从而在服务端 / 客户端时间一致的前提下,解决了 HOTP 需要同步计数器的问题。同时,TOTP 算法需要用到当前时间,需要现场计算,无法提前算好打印出来。默认情况下,TOTP 在间隔时间 TS 内都能通过校验,并不是一次有效。这个问题可以通过在服务端记录最后一次 TC 来解决,由于 TS 一般很短,通常也可以忽略。
有一个名为 speakeasy 的 Node 包,可以用来生成 HOTP 或 TOTP,直接通过 npm install speakeasy
就能安装。Google 出品了一个名为 Authenticator 的客户端,支持 HOTP 和 TOTP,适用于各大移动平台。这里就以
speakeasy
和 Google Authenticator
为例说明如何在 Node 中使用 2FA。
首先,通过以下代码可以生成密钥 K:
var speakeasy = require('speakeasy');
var key = speakeasy.generate_key({});
console.log(key);
{
ascii: '@H?e#/)iOxS65k09h8g2DJ?/EavR7CCs',
hex: '40483f65232f29694f785336356b303968386732444a3f2f4561765237434373',
base32: 'IBED6ZJDF4UWST3YKM3DK2ZQHFUDQZZSIRFD6L2FMF3FEN2DINZQ'
}
speakeasy 默认会生成三种格式的密钥,其中 Google Authenticator 需要用到 base32。服务端需要为每个用户生成并存储密钥。
上面一步生成的密钥,用户可以在 Google Authenticator 里手动录入,更方便的做法是把密钥转成二维码。Google Authenticator 支持的二维码格式是:
otpauth://TYPE/LABEL?PARAMETERS
TYPE
支持 hotp 或 totp;LABEL
用来指定用户身份,例如用户名、邮箱或者手机号,前面还可以加上服务提供者,需要做
URI 编码。它是给人看的,不影响最终校验码的生成。
PARAMETERS
用来指定参数,它的格式与 URL 的 Query 部分一样,也是由多对 key 和 value 组成,也需要做 URL
编码。可指定的参数有这些:
另外,Google Authenticator 也不支持指定 TOTP 算法中起始时间戳 T0。下面是两个完整的例子,将他们生成二维码,通过 Google Authenticator 扫描就可以添加进去了:
otpauth://hotp/TEST:ququ@test.com?secret=IBED6ZJDF4UWST3YKM3DK2ZQHFUDQZZSIRFD6
L2FMF3FEN2DINZQ&issuer=ququblog&counter=0
otpauth://totp/TEST:ququ@test.com?secret=IBED6ZJDF4UWST3YKM3DK2ZQHFUDQZZSIRFD6L2FMF3FEN2DINZQ&issuer=ququblog
有关 Google Authenticator 二维码格式的更多说明,可以参考官方 wiki。
以下代码分别可以生成 HOTP 和 TOTP,用于服务端验证用户提交的校验码是否正确。需要注意的是,代码中的 key 参数默认是 ascii 格式,传其他格式需要指定 encoding 参数。
speakeasy.hotp({ key : key.ascii, counter : counter};
speakeasy.totp({ key : key.ascii});
服务端根据用户信息读出密钥(针对 HOTP 还需要读出最新的计数器),算出服务端校验码,跟用户提交的校验码比较,如果一致就验证通过。针对 HOTP,验证失败需要尝试同步计数器;验证通过需要更新服务端计数器。
最后我打算聊一聊我能想到的关于 OTP 的安全风险点:
首先,无论是 HOTP 和 TOTP,在服务端验证时需要用到密钥,这就需要在服务端存储密钥,如果服务端代码或者数据库发生泄露,密钥可能会被人拿到。其次,生成 二维码这一步也需要用到密钥,如果用户电脑存在恶意软件,也存在密钥泄露的风险。另外,手机 2FA 客户端也需要存储密钥,如果安全防护没做好,也有密钥被其他 APP 盗取的风险(所以从正规途径下载知名公司开发的 2FA 客户端,并且手机不要越狱或 ROOT 很重要)。后两个问题,使用独立的 OTP 硬件设备应该能解决。
但是,无论是何种 OTP,一定会存在需要禁用 OTP,或者更换密钥的场景(例如 HOTP 中计数器达到最大值,手机丢失或 OTP 硬件设备丢失),如果这里考虑不周,一样会影响账户安全。所以,WEB 安全也是一个系统工程,各方面都需要考虑周全。
注:我现在已经用 Authy 替代 Google Authenticator 了。Authy 可以方便地实现备份和多终端同步,而 Google Authenticator 在 iPhone 恢复备份时会丢失所有记录。
京东创始人刘强东和其妻子章泽天最近成为了互联网舆论关注的焦点。有关他们“移民美国”和在美国购买豪宅的传言在互联网上广泛传播。然而,京东官方通过微博发言人发布的消息澄清了这些传言,称这些言论纯属虚假信息和蓄意捏造。
日前,据博主“@超能数码君老周”爆料,国内三大运营商中国移动、中国电信和中国联通预计将集体采购百万台规模的华为Mate60系列手机。
据报道,荷兰半导体设备公司ASML正看到美国对华遏制政策的负面影响。阿斯麦(ASML)CEO彼得·温宁克在一档电视节目中分享了他对中国大陆问题以及该公司面临的出口管制和保护主义的看法。彼得曾在多个场合表达了他对出口管制以及中荷经济关系的担忧。
今年早些时候,抖音悄然上线了一款名为“青桃”的 App,Slogan 为“看见你的热爱”,根据应用介绍可知,“青桃”是一个属于年轻人的兴趣知识视频平台,由抖音官方出品的中长视频关联版本,整体风格有些类似B站。
日前,威马汽车首席数据官梅松林转发了一份“世界各国地区拥车率排行榜”,同时,他发文表示:中国汽车普及率低于非洲国家尼日利亚,每百户家庭仅17户有车。意大利世界排名第一,每十户中九户有车。
近日,一项新的研究发现,维生素 C 和 E 等抗氧化剂会激活一种机制,刺激癌症肿瘤中新血管的生长,帮助它们生长和扩散。
据媒体援引消息人士报道,苹果公司正在测试使用3D打印技术来生产其智能手表的钢质底盘。消息传出后,3D系统一度大涨超10%,不过截至周三收盘,该股涨幅回落至2%以内。
9月2日,坐拥千万粉丝的网红主播“秀才”账号被封禁,在社交媒体平台上引发热议。平台相关负责人表示,“秀才”账号违反平台相关规定,已封禁。据知情人士透露,秀才近期被举报存在违法行为,这可能是他被封禁的部分原因。据悉,“秀才”年龄39岁,是安徽省亳州市蒙城县人,抖音网红,粉丝数量超1200万。他曾被称为“中老年...
9月3日消息,亚马逊的一些股东,包括持有该公司股票的一家养老基金,日前对亚马逊、其创始人贝索斯和其董事会提起诉讼,指控他们在为 Project Kuiper 卫星星座项目购买发射服务时“违反了信义义务”。
据消息,为推广自家应用,苹果现推出了一个名为“Apps by Apple”的网站,展示了苹果为旗下产品(如 iPhone、iPad、Apple Watch、Mac 和 Apple TV)开发的各种应用程序。
特斯拉本周在美国大幅下调Model S和X售价,引发了该公司一些最坚定支持者的不满。知名特斯拉多头、未来基金(Future Fund)管理合伙人加里·布莱克发帖称,降价是一种“短期麻醉剂”,会让潜在客户等待进一步降价。
据外媒9月2日报道,荷兰半导体设备制造商阿斯麦称,尽管荷兰政府颁布的半导体设备出口管制新规9月正式生效,但该公司已获得在2023年底以前向中国运送受限制芯片制造机器的许可。
近日,根据美国证券交易委员会的文件显示,苹果卫星服务提供商 Globalstar 近期向马斯克旗下的 SpaceX 支付 6400 万美元(约 4.65 亿元人民币)。用于在 2023-2025 年期间,发射卫星,进一步扩展苹果 iPhone 系列的 SOS 卫星服务。
据报道,马斯克旗下社交平台𝕏(推特)日前调整了隐私政策,允许 𝕏 使用用户发布的信息来训练其人工智能(AI)模型。新的隐私政策将于 9 月 29 日生效。新政策规定,𝕏可能会使用所收集到的平台信息和公开可用的信息,来帮助训练 𝕏 的机器学习或人工智能模型。
9月2日,荣耀CEO赵明在采访中谈及华为手机回归时表示,替老同事们高兴,觉得手机行业,由于华为的回归,让竞争充满了更多的可能性和更多的魅力,对行业来说也是件好事。
《自然》30日发表的一篇论文报道了一个名为Swift的人工智能(AI)系统,该系统驾驶无人机的能力可在真实世界中一对一冠军赛里战胜人类对手。
近日,非营利组织纽约真菌学会(NYMS)发出警告,表示亚马逊为代表的电商平台上,充斥着各种AI生成的蘑菇觅食科普书籍,其中存在诸多错误。
社交媒体平台𝕏(原推特)新隐私政策提到:“在您同意的情况下,我们可能出于安全、安保和身份识别目的收集和使用您的生物识别信息。”
2023年德国柏林消费电子展上,各大企业都带来了最新的理念和产品,而高端化、本土化的中国产品正在不断吸引欧洲等国际市场的目光。
罗永浩日前在直播中吐槽苹果即将推出的 iPhone 新品,具体内容为:“以我对我‘子公司’的了解,我认为 iPhone 15 跟 iPhone 14 不会有什么区别的,除了序(列)号变了,这个‘不要脸’的东西,这个‘臭厨子’。