具透 Plus | iOS 26 密码导出功能幕后;Pixel 5G 网络启用方案遭封堵
苹果在iOS和macOS 26中引入新功能,支持通过标准化API安全迁移密码数据,解决传统工具间格式不兼容问题,并兼容通行密钥技术。 2025-10-16 09:56:24 Author: sspai.com(查看原文) 阅读量:36 收藏

iOS/macOS26密码导出功能幕后@PlatyHsu:如今,密码管理工具的选择不可谓不多。苹果也凑上了热闹,在去年的系统更新中加入了独立的「密码」app。然而,要在这些工具之间迁移,传统上是非常困 ...

iOS/macOS 26 密码导出功能幕后

@PlatyHsu:如今,密码管理工具的选择不可谓不多。苹果也凑上了热闹,在去年的系统更新中加入了独立的「密码」app。然而,要在这些工具之间迁移,传统上是非常困难的。每个工具都使用互不兼容的格式;即使导出为 CSV 格式,由于双方的字段定义和功能集不同,也几乎无法无损转换。

近年 passkey(通行密钥)的普及进一步加重了这个问题。passkey 基于非对称加密,其中的私钥存放在设备的安全芯片里,公钥存放在网站或应用的服务器上。登录时,网站用公钥生成一个只有使用私钥才能通过的验证(challenge),从而验证身份。

显然,要保证这个机制的安全,私钥必须牢牢绑定在硬件上,不可轻易复制或导出,否则就和一个普通的密码无异了。因此,目前 passkey 的迁移和同步通常都是厂商在自己的生态内通过加密传输实现的,很难互相打通。这就导致了 passkey 经常受到的一种批评:明明是为了通用和便捷而采用的技术,反而造成了更多的封闭和麻烦。

macOS 26 和 iOS 26 引入的一些新变化,显示出这些问题得到改善的迹象。WWDC25 讲座《通行密钥更新》提到,通过一项与 FIDO 联盟(一个成立于 2013 年,旨在制定和推广身份验证标准的产业协会)成员合作的标准化数据格式,现在可以安全地在密码管理器之间迁移。迁移过程中,无须向磁盘导出任何不安全的明文密码,数据完全在应用之间传输。

你目前已经可以在 iOS 26 上尝试这个功能。首先,安装第三方密码管理器 Bitwarden,这是目前唯一正式支持接收 Password app 导出数据的第三方工具。然后,在自带的 Password app 中点击右上角的「…」,选择 Export Data to Another App。从列表中选择要导出的条目,再选择导出到 Bitwarden。经过 Face ID 验证后,就可以在 Bitwarden 中看到结果了。整个过程不需要导出外部文件,也不需要在应用之间来回切换。

(macOS 上的 Password app 也有相同功能的菜单项,但本文写作时暂时还没有发现能显示在导出选项中的第三方工具。不知为何,iOSmacOS 的用户手册都完全忽略了这项新功能。)

要支持这项新的导入和导出体验,第三方应用需要支持 iOS/macOS 26 的新增 API ASCredentialExportManagerASCredentialImportManager。不过,如上述 WWDC 讲座所介绍,这些并不是苹果独自发明的,而是对一项通用标准的实现。

根据这项名为「凭证交换协议」(Credential Exchange Protocol, CXP)的标准,新旧两个密码管理器可以根据这样的流程来安全传输凭证:

       ┌──────────────────────────────────────────────────────┐
       │                  Authorizing Party                   │
       └─────┬──────────────────────────────────────────┬─────┘

             │   (2) Determine        (1) Create Export │
                  Migration Key              Request
┌────────────┴──┐                                  ┌────┴──────────┐
│               ◀─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┤               │
│               │                                  │               │
│               │                                  │               │
│               │                                  │               │
│┌─────────────┐│                                  │               │
││ (3)Encrypt  ││                                  │               │
││ Credential  ││                                  │               │
││    Data     ││                                  │               │
│└─────────────┘│                                  │               │
│               │       (4) Send Export Response   │               │
│               │─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ▶┌─────────────┐│
│               │                                  ││ (5) Decrypt ││
│               │                                  ││   Bundle    ││
│               │                                  │└─────────────┘│
│               │                                  │               │
│               │                                  │               │
│               │                                  │               │
│               │                                  │               │
│   Exporter    │                                  │   Importer    │
│               │                                  │               │
└───────────────┘                                  └───────────────┘

用通俗的话来描述:

  1. 导入方(新密码管理器)创建一个导出请求,其中包含请求范围、自己的公钥、加密配置以及一项身份验证等;
  2. 导出方(旧密码管理器)收到请求后,提示用户授权。获得用户同意后,用导入方的公钥和自己的私钥计算出一个加密密钥,用来加密导出的凭证数据。同时,在导入方发来的身份验证上签名,以证明自己的身份;
  3. 导出方将加密的凭证数据、自己的公钥以及对身份验证的签名回复打包成一个导出响应,发送给导入方;
  4. 导入方收到响应后,验证签名,确认导出方的身份。然后,使用自己的私钥和导出方的公钥,独立计算出加密密钥,进而解密凭证数据,解析后存入自己的数据库中。

可以看出,这个机制的一个优势在于加密密钥无需传输,而是由双方独立计算得出。这确保了即使传输过程被拦截,攻击者也无法解密凭证数据。

此外,CXP 还支持多种导出「模式」来适应不同的场景。iOS 和 macOS 此次新增的导出功能属于「直接传输」(direct)模式,也就是两个应用通过 API 直接通讯并传输响应。而如果涉及跨设备迁移等无法直接传输的情况,也可以使用「间接传输」(indirect)模式,让旧应用将相应内容存储为一个加密文件,然后手动导入新应用。最后还有一种特殊的「自传输」(self)模式,本质上就是一种安全备份功能,可以将凭证数据导出为加密文件,以便日后恢复。

解决了传输安全性的问题,还要考虑如何实现不同应用之间的格式兼容。这就是与 CXP 配套的「凭证传输格式」(Credential Exchange Format, CXF)要解决的问题。CXF 实际上提供了一套用 JSON 来描述凭证信息的通用模板,它的顶层结构大概长得像这样:

{
    "version": {
        "major": 1,
        "minor": 0
    },
    "exporterRpId": "exporter.example.com",
    "exporterDisplayName": "Exporter app",
    "timestamp": 1705228800,
    "accounts": [
        {
            "id": "DZSXp7iBQY-Fg-OofakQtQ",
            "username": "jane_smith",
            "email": "[email protected]",
            "fullName": "Jane Smith",
            "items": [
                {
                    "id": "9OF-QjVDQo2Wp2xWPw6ZhA",
                    "creationAt": 1705142400,
                    "modifiedAt": 1705228800,
                    "title": "GitHub Login",
                    "scope": {
                        "urls": ["https://github.com"],
                    },
                    "credentials": [
                        // ...
                    ]
                },
                // ...
            ],
            "collections": [
                // ...
            ]
        }
    ]
}

可以看出,数据的开头给出了格式版本、导出方信息和时间戳等信息,然后是一个 accounts 数组,其中包含了此次导出的一或多个用户账户,是导出数据的核心。accounts 的内部是一个三层结构:


文章来源: https://sspai.com/prime/story/inside-release-notes-251016
如有侵权请联系:admin#unsafe.sh