加拿大魁北克疫苗护照的缺陷:分析
魁北克政府允许存储和验证疫苗接种护照的移动应用程序(VaxiCode 和 VaxiCode Verif)的推出在上周引起了大量墨水流动。这是有充分理由的;自 2021 年 9 月 1 日起,所有非必要服务商户都将使用 VaxiCode Verif 应用程序。
和许多其他专家一样,我在去年 5 月第一次接种疫苗时收到二维码后立即对其内容进行了分析。上周,我还分析了魁北克政府建立并由Akinox开发的两个应用程序。
这篇博文从技术角度解释了魁北克政府建立的疫苗护照系统的工作原理,以及我们在 VaxiCode Verif 中发现的漏洞的详细信息,该漏洞允许应用程序被迫将非政府颁发的二维码识别为有效的。目前,无法确认这与加拿大广播电台上周五报道的“路易斯”发现的漏洞相同,因为尚未发布任何技术细节。
我们将周日发现的漏洞告知了 Akinox,并确认最近几天发布的 iOS 版 VaxiCode Verif 1.0.2 更新修复了该漏洞。尚未分析 Android 版本的应用程序,但 VaxiCode 和 VaxiCode Verif 使用Expo框架,该框架允许使用相同的源代码生成 iOS 和 Android 应用程序。因此,两个平台上的应用程序可能是等效的。
让我们深入了解魁北克疫苗护照的内容
首先,让我们看看二维码包含什么。一般来说,二维码只包含文字。它通常是一个 URL。
但让我们回到魁北克疫苗护照申请。我们注意到此二维码中包含的 URL 以 开头shc:/
。“shc”实际上是SMART Health Cards的首字母缩写,该规范定义了用于交换有关个人疫苗接种状态信息的格式。该规范诞生于 2021 年,目的是能够签发这本著名的疫苗护照,并能够验证其真实性。这与美国几个州(包括加利福尼亚州、纽约州和路易斯安那州)选择的标准相同。该规范的制定由疫苗接种证书倡议牵头,一个由公共和私人组织组成的联盟,致力于在全球范围内安全部署护照。为魁北克政府开发 VaxiCode 和 VaxiCode Verif 的公司 Akinox 是该组织的成员。
该规范描述了如何将 URL 中的数字解码为可读内容。
信息被解码为 JSON 网络令牌 (JWT),或者更具体地说是 JSON 网络签名 (JWS),因为它是一个签名令牌。SHC 规范并没有重新发明轮子:JWT 是一种用于交换加密或数字签名信息的现有技术。
如果您想了解有关疫苗护照内容的更多信息,您可以使用François Proulx 开发的在线工具从移动设备轻松检查。
这些信息应该加密吗?
许多人建议对二维码中的信息进行加密。这似乎是保护它的好方法;然而,破译这些信息太容易了。该信息必须被 VeriCode Verif 理解,因此应用程序应包含解密密钥。提取密钥后,任何人都可以解密二维码。这会给人一种安全的错误印象,并引起公众的更多批评。
由于这些原因,SHC 协议不提供加密方法。但是,它确实需要数字签名。
数字签名如何工作?
数字签名基于非对称加密,这意味着使用密钥对。这对由一个私钥组成,只有发行人(这里是魁北克政府)才能对数据进行签名,还有一个所谓的公钥,用于验证是否使用私钥进行了签名。
除其他外,非对称加密用于加密 Internet 上的通信。在没有私钥或从公钥猜测私钥的情况下,没有已知的攻击可以签名。
这也意味着优先考虑的是不惜一切代价保护这个私钥。破坏此密钥将允许生成加密有效的二维码。我们发现的缺陷并非如此:我们不需要私钥来伪造 VaxiCode Verif 认为有效的疫苗证明。相反,问题在于 VaxiCode Verif 中验证算法的实现。
VaxiCode Verif 的缺陷究竟是什么?
SMART Health Cards 规范旨在允许多个疫苗证据发布者的可能性。这反映了每个国家或地区都有责任出具自己的证据的现实。因此,每个政府都有自己的一对密钥来签署和验证护照。
SHC 规范要求发行实体在 Internet 上提供其公钥。疫苗证明在“iss”(issuer 的缩写)字段中包含指向发行人网站的 URL 。验证应用程序应通过连接.well-known/jwks.json
到此 URL 来找到发行者的公钥。
该规范没有定义(至少目前)确定发行人是否值得信赖的方法。
Akinox 选择在 VaxiCode 和 VaxiCode Verif 中包含魁北克政府的公钥。当发行人是魁北克政府时(特别iss
是如果是https://covid19.quebec.ca/PreuveVaccinaleApi/issuer
),应用程序将使用此密钥。然而,下载第三方发行者密钥的代码仍在应用程序中,即使它不是必需的。
该漏洞在于,一旦下载了公钥,就可以使用它来验证任何其他通行证,而无需检查它是否与颁发者字段 ( iss
)的内容匹配。
这是显示伪造疫苗证明有效的攻击场景:
- 攻击者生成密钥对并在以下位置提供公钥
https://example.org/.well-known/jwks.json
- 他以二维码的形式生成了两张智能健康卡:
- 第一个是使用任意内容创建的,前提是
iss
是https://example.org
。 - 第二个是使用想要冒充接种疫苗的人的个人信息以及
iss
指向合法政府域的字段创建的,并使用步骤 1 中生成的密钥对其进行签名。 - 在验证疫苗护照期间,攻击者首先出示第一个二维码。此验证将被 VaxiCode Verif 拒绝,但会强制应用程序下载攻击者的公钥并将其添加到其受信任的钥匙串中。
- 攻击者随后将展示第二个二维码,该二维码将被 VaxiCode Verif 验证为合法。
自周日起在 Apple App Store 上可用的 1.0.2 版修复了该问题。此更新完全删除了从发行者的 URL 下载公钥的功能。
什么可以做得更好?
负责部署疫苗证明的当局和开发人员受到难以缓解的限制:时间。魁北克疫苗接种证明的整个开发和部署是在几个月内完成的。尽管存在一些缺陷,但该系统正在运行。
为了透明起见,魁北克政府可能错过了发布其制作的应用程序源代码的好机会。毕竟,这些应用程序没有什么可隐藏的,也没有什么秘密。缺陷的快速发现表明,大量专家的分析提高了此类应用程序的安全性。源代码的发布和专家的分析可能避免了可能影响公众信心的丑闻,因为所有人都可以自行检查安全性。
也有人觉得魁北克疫苗护照所载的个人资料过多。在这方面,本来可以制作包含较少信息的较轻版本的护照。也就是说,这种较轻的版本可能在魁北克以外地区无法使用,因为确定一个人是否受到保护的规则可能因地区而异(哪些疫苗被认为是有效的,剂量多少等)。
这就是瑞士选择的“COVID light证书”。还应该指出的是,瑞士应用程序的源代码也已经发布了几个月。
我们没有测试允许发放疫苗护照的服务器,因为我们既没有魁北克政府或 Akinox 的授权,也没有获得这样做的许可。与魁北克提供的应用程序分析不同,这将构成对远程系统的攻击,可能导致服务中断的风险。
结论
我们的分析首先考察了 CHS 规范的发展历史,该规范是在国际上专门为发布 COVID-19 疫苗接种确认而制定的。然后我们解释了使用非对称加密技术对数据进行签名的重要性,在这种情况下,确保所提供的疫苗接种证明的有效性。但是,我们发现验证算法的实现存在缺陷,该缺陷允许伪造 VaxiCode Verif 显示为合法的疫苗证明。我们将这个缺陷通知了 Akinox,并且在应用程序更新后即在几天内修复了它。最后,我们指出了提高这些应用程序源代码透明度的潜在好处。
通过这个分析,我认为,虽然 VaxiCode Verif 在发布时存在一些问题,但该系统所基于的技术是可靠的。在我看来,使用现有标准和技术的想法是一个很好的决定。它使用 SMART Health Cards 协议确保区域之间的签名安全性和互操作性。在我看来,拒绝有效疫苗护照的系统缺陷会产生比相反更严重的影响,而这里并非如此。
问题在短短几天内得到解决表明各方都想要一个安全的系统。总有需要改进的地方,但 SHC 提出的数字签名的使用迄今为止是安全的。
