文章目录
- 1.Introduction
- 2. Terminology
- 3.凭证传输工作流程
- 4. API connection details
- 5. HTTP Headers
- 6. HTTP access methods
- 6.1. CreateMailbox
- 6.1.1. Endpoint
- 6.1.2. Request Parameters:
- 6.1.3. Consumes
- 6.1.4. Produces
- 6.1.5. Request body
- 6.1.6. Responses
- 6.2. UpdateMailbox
- 6.2.3. Consumes
- 6.2.4. Produces
- 6.2.5. Request body
- 6.4. ReadDisplayInformationFromMailbox
- 6.5. ReadSecureContentFromMailbox
- 6.5.1. Endpoint
- 6.5.2. Request Parameters
- 6.6. RelinquishMailbox
- 7. Security Considerations
- 8. IANA Considerations
1.Introduction
目前,在同一平台或不同平台的两个设备之间安全地传输数字凭证还没有标准的方法。本文档通过引入中继服务器提出了解决方案,该服务器允许两个设备安全地交换加密的配置信息。中继服务器通过创建和管理临时邮箱存储来解决这个问题。
每个邮箱可以通过URL中的唯一邮箱标识符被设备引用。指向加密的配置信息的URL将直接通过各种渠道(如短信、电子邮件、消息应用程序)在设备之间传递。安全注意事项部分提供了关于安全传递URL和密钥的建议。
本文档描述了一个超文本传输协议(HTTP)应用程序编程接口(API),允许发送方和接收方设备与中继服务器进行交互,以执行安全的凭证传输。原文地址
2. Terminology
-
中继服务器(Relay Server)- 一种Web应用程序,向设备提供安全凭证传输API。它用于在两个设备(发送方和接收方)之间安全地传输配置信息。
-
发送方设备(Sender device)- 发起将配置信息传输给接收方设备的设备,以便接收方可以注册或配置此凭证。
-
接收方设备(Receiver device)- 从发送方设备接收配置信息,并使用它来注册或配置凭证信息的设备。
-
配置合作伙伴(Provisioning Partner)- 一个实体,在设备上促进凭证信息的生命周期。生命周期可能包括凭证的配置、凭证的终止、凭证的更新。本文档不涉及与配置合作伙伴的API。
-
配置信息(Provisioning Information)- 一组数据字段,允许设备生成凭证信息或从配置合作伙伴接收凭证信息并在本地安装。发送方或接收方设备会对配置信息的整个内容进行加密,因此中继服务器无法看到其内容。配置信息的结构特定于配置合作伙伴或凭证类型,超出了本文档的范围。
-
凭证信息(Credential Information)- 一组数据字段,用于在接收方设备上便捷地注册或配置凭证信息。
-
密钥(Secret)- 由发送方和接收方设备共享的对称加密密钥,用于加密存储在中继服务器上的配置信息。密钥在整个凭证传输流程中保持不变(每个完整传输使用一个密钥)。存储在中继服务器上的配置信息始终使用该密钥进行加密。在有状态的传输流程中,发送方和接收方设备通过中继服务器交换的所有信息都会使用该密钥进行加密。
-
凭证垂直(Credential Vertical)- 凭证所属的广泛行业垂直领域。例如,凭证可以属于汽车或家庭垂直领域。
API参数:
-
设备声明(Device Claim)- 一个唯一的令牌,允许调用者从邮箱中读取/写入数据。应该能够有一个发送方设备和一个接收方设备从邮箱中读取/写入安全负载。发送方设备提供设备声明以创建邮箱。当中继服务器收到来自发送方设备的请求时,它会创建一个邮箱,并将该发送方的设备声明与邮箱绑定。当接收方设备首次从邮箱中读取数据时,它会向中继服务器呈现其设备声明,中继服务器会将邮箱绑定到给定的接收方设备。因此,发送方和接收方设备都绑定到邮箱中(允许从中读取/写入)。只有呈现有效设备声明的发送方和接收方设备才可以向邮箱发送后续的读取/更新/删除调用。该值应为唯一的UUID[RFC4122]。发送方和接收方必须使用不同的设备声明值。实现应为新邮箱分配唯一的值(避免重用值)。
-
通知令牌(Notification Token)- 由发送方或接收方设备存储在中继服务器上的邮箱中的短期或长期唯一令牌,允许中继服务器向发送方或接收方设备发送推送通知,通知其邮箱中的更新。
-
邮箱标识符(Mailbox Identifier)- 在创建邮箱时由中继服务器生成的给定邮箱的唯一标识符。该值为UUID[RFC4122]。
3.凭证传输工作流程
定义了两种凭证传输流程:
- 无状态(中继服务器促进单个凭证数据传输:发送方 -> 中继 -> 接收方)
- 有状态(中继服务器促进额外的数据传输-在此流程中有多个数据传输以准备接收方进行注册或配置凭证数据)。中继服务器不限制发送方和接收方设备之间此类数据传输的数量。
以下是详细信息:
无状态和有状态的过程共享以下共同步骤。
该过程始于发送方设备组成一组配置信息,使用一个密钥加密并将加密的配置信息存储在邮箱中的中继服务器上。中继服务器生成一个唯一的邮箱标识符作为CreateMailbox调用的一部分,使用一个可靠的熵源(最好是基于硬件的熵源)创建该标识符。发送方设备生成一个唯一的令牌 - 发送方设备声明,并将其存储到邮箱中。设备声明允许发送方设备呈现它来读取和写入邮箱中的数据,从而将其与邮箱绑定。发送方设备调用中继服务器上的CreateMailbox API端点,以创建一个邮箱。一旦创建了邮箱,它将有限的生命周期。当过期时,邮箱应被删除(参考DeleteMailbox端点)。在CreateMailbox调用的请求中,邮箱配置包含一个必需的"expiration"参数(参考mailboxConfiguration请求参数)。中继服务器负责定期检查已过期的邮箱并删除它们。中继服务器构建一个唯一的URL链接,指向该邮箱(例如,“https://relayserver.example.com/v1/m/1234567890”),并将其返回给发送方设备,后者通过通信渠道(如短信、电子邮件、iMessage)将该链接直接发送给接收方设备。请参阅"安全考虑"部分获取更多详细信息。接收方设备获得URL链接和密钥后,生成一个唯一的令牌 - 接收方设备声明,并将其传递给中继服务器,以便从邮箱中读取加密的配置信息。中继服务器最终通过提供的发送方设备声明(在创建邮箱时提供)和接收方设备声明(在从邮箱中读取安全内容时提供),将发送方设备和接收方设备与该邮箱绑定起来。只有绑定的设备才被允许读取、写入数据到邮箱,或者删除该邮箱。
3.1. Stateless workflow
无状态工作流程完成了“凭证传输工作流程”部分中描述的共同步骤,然后通过完成以下步骤完成传输。接收方设备从中继邮箱中读取加密的配置信息后,使用从发送方接收到的密钥对其进行解密,并在设备上启动凭证注册或配置过程。一旦接收方设备成功配置了凭证,它会向中继服务器发送DeleteMailbox调用来删除该邮箱。
Sender Relay Receiver
| | |
Create mailbox with | CreateMailbox | |
Provisioning Info |——---------------->| |
encrypted with |<<-.-.-.-.-.-.-.-.-| |
Secret |URL link to mailbox| |
| | |
Send URL link to | | URL link and Secret |
mailbox and Secret |-------------------------------------------------->|
| | |
| | ReadSecureContentFromMailbox |
| |<------------------------------|
| |-.-.-.-.-.-.-.-.-.-.-.-.-.-.->>| Decrypt with Secret to get Prov Info
| | encrypted info |
| | |
| | DeleteMailbox |
| |<------------------------------| Provision or Register credentials
| |-.-.-.-.-.-.-.-.-.-.-.-.-.-.->>|
| | OK |
3.2. Stateful workflow
有状态工作流程完成了“凭证传输工作流程”部分中描述的共同步骤,然后通过完成以下步骤来完成传输。
接收方设备通过URL从邮箱中下载加密的配置信息,并使用从发送方设备接收到的密钥对其进行解密。然后,接收方设备生成一个新的配置信息结构(例如数字密钥),并使用相同的密钥对其进行加密,然后将有效载荷存储在中继服务器上的同一邮箱中。除了加密的有效载荷外,接收方还在给定的邮箱中存储了接收方通知令牌。
接收方设备收到加密的配置信息后,中继服务器使用发送方通知令牌向发送方设备发送通知。
发送方设备收到中继服务器的通知后,从邮箱中读取安全内容,并使用相同的密钥对所有内容进行解密。发送方设备生成新的配置信息,使用该密钥对所有字段进行加密,并将所有数据存储在中继服务器上的同一邮箱中。
中继服务器存储了上述数据后,使用接收方通知令牌向接收方设备发送通知。接收方设备收到通知后,读取加密的配置信息,使用相同的密钥对数据进行解密,并使用这些数据来完成设备上的凭证注册或配置。
一旦接收方设备成功注册或配置了凭证,它会向中继服务器发送DeleteMailbox调用来删除该邮箱。发送方设备可以随时通过删除其创建的邮箱来终止安全凭证传输。在中继服务器上删除邮箱会停止任何正在进行的凭证传输过程。
Sender Relay Receiver
| | |
Create and encrypt | CreateMailbox | |
Provisioning Info 1|---------------------------->| |
encrypted with |<<-.-.-.-.-.-.-.-.-.-.-.-.-.-| |
Secret | URL link to mailbox | |
| | |
| | URL link and Secret |
Send URL link to |---------------------------------------------------------->|
mailbox and Secret | | |
| |ReadSecureContentFromMailbox |
| |<----------------------------|
| |-.-.-.-.-.-.-.-.-.-.-.-.-.->>| Decrypt with Secret for ProvInfo1
| | encrypted info |
| | |
| |UpdateMailbox(encrypted info)| Update with ProvInfo2
| |<----------------------------| encrypted with Secret
| Push Notification |-.-.-.-.-.-.-.-.-.-.-.-.-.->>| ProvInfo2 = new Provisioning Info
|<............................| OK |
| | |
|ReadSecureContentFromMailbox | |
|---------------------------->| |
Decrypt with Secret |<<-.-.-.-.-.-.-.-.-.-.-.-.-.-| |
to get ProvInfo2 | encrypted info | |
| | |
|UpdateMailbox(encrypted info)| |
Update with |—-----------—--------------->| |
ProvInfo3 encrypted |<<-.-.-.-.-.-.-.-.-.-.-.-.-.-| Push Notification |
with Secret. | OK |............................>|
ProvInfo3 = new | | |
Provisioning Info | |ReadSecureContentFromMailbox |
| |<----------------------------|
| |-.-.-.-.-.-.-.-.-.-.-.-.-.->>| Decrypt with Secret for ProvInfo3
| | encrypted info |
| | |
| | DeleteMailbox |
| |<----------------------------| Provision or Register credentials
| |-.-.-.-.-.-.-.-.-.-.-.-.-.->>|
| | OK |
3.3. Provisioning Information Structure
Provisioning Information是通过中继服务器在发送方设备和接收方设备之间传输的数据。每个用例都定义了自己专业化的Provisioning Information格式,但所有格式至少必须遵循以下结构。格式可以自由定义新的顶层键,因此客户端不应感到惊讶,如果一个意外格式的消息具有专门的顶层键。
3.3.1. Provisioning Information Format
{
"format" : "digitalwallet.carkey.ccc",
"content": {
// Format specific fields
}
}
3.3.2. Provisioning Information Encryption
Provisioning Information将以加密形式存储在中继服务器上。用于加密Provisioning Information的密钥应通过“共享URL”(指向邮箱的URL链接)提供给接收方设备。加密的有效载荷应该是一个数据结构,包含以下键值对:
“type”(字符串,必需)- 使用的加密算法和模式。
“data”(字符串,必需)- 加密后的Provisioning Information的Base64编码二进制值,也就是密文。
请参考[RFC5116]以获取有关加密算法的详细信息。
以下算法和模式是必须实现的:
- “AEAD_AES_128_GCM”:使用128位密钥长度的AES对称加密算法,在GCM模式下进行加密,不使用填充。初始化向量(IV)的长度为96位,由随机生成,并且标签长度为128位。
- “AEAD_AES_256_GCM”: 使用256位密钥长度的AES对称加密算法,在GCM模式下进行加密,不使用填充。初始化向量(IV)的长度为96位,由随机生成,并且标签长度为128位。
以下是安全有效载荷格式的示例(Figure 4):
{
"type" : "AEAD_AES_128_GCM",
"data" : "IV ciphertext tag"
}
3.4. Share URL
“共享URL”是发送设备发送给接收设备的URL,允许接收设备检索存储在中继服务器上的Provisioning Information。共享URL由以下字段组成:
https://{RelayServerHost}/v{ApiVersion}/m/{MailboxIdentifier}?v={CredentialVertical}#{Secret}
3.4.1. Credential Vertical in Share URL
当用户在接收设备上与共享URL进行交互时,了解此共享所属的Credential Vertical可能会很有帮助。如果接收设备具有多个可以处理共享URL的应用程序,则这一点尤为重要。例如,接收设备可能希望在其钱包应用程序中处理一般访问共享,但在特定汽车应用程序中处理汽车钥匙共享。
为了正确路由共享URL,发送方可以将Credential Vertical作为查询参数包含在共享URL中。加密有效载荷中不能包含Credential Vertical,因为接收设备可能需要在检索安全有效载荷之前打开正确的应用程序。Credential Vertical查询参数使用“v”键,并支持以下类型。如果未提供Credential Vertical,则假定这是一个通用访问共享URL。
https://relayserver.example.com/v1/m/2bba630e-519b-11ec-bf63-0242ac130002?v=c#hXlr6aRC7KgJpOL
发送设备在构建将要发送给接收设备的完整共享URL时,可以添加Credential Vertical查询参数。
4. API connection details
Relay服务器的API端点必须通过使用https URI [RFC2818]进行HTTP访问,并应使用默认的https端口。请求和响应体应该格式化为JSON或HTML(基于API端点)。所有接口使用的通信协议必须是HTTPS。所有字符串应该使用UTF-8编码(Unicode规范化形式C(NFC))。API版本应该包含在所有接口的URI中。本文档最新更新时的版本为v1。对于主要的API更改或对现有API的不兼容迭代,版本应递增1。
5. HTTP Headers
5.1. Mailbox-Request-ID
所有与Relay服务器的请求和响应都将具有一个名为"Mailbox-Request-ID"的HTTP头。相应的API响应将具有相同的HTTP头,它将回显请求头中的值。这用于标识与特定API请求和响应对相关联的请求。该值应为UUID[RFC4122]。请求发起方应将响应中的该头的值与请求中发送的值进行匹配。如果未收到响应,调用方可以重试使用相同的"Mailbox-Request-ID"发送请求。Relay服务器应根据调用方的设备声明(Device Claim)存储最后成功处理的"Mailbox-Request-ID"的值。建议使用"设备声明"到"Mailbox-Request-ID"的键值对来存储每个设备的最后成功处理的请求。如果收到具有重复的"Mailbox-Request-ID"的请求,Relay服务器应以状态码201响应给调用方,并忽略重复请求体内容。
5.2. Device-Claim
创建邮箱的请求可以包含此头。该值表示设备认证(字符串,可选)-可选的远程OEM设备专有认证数据。
6. HTTP access methods
6.1. CreateMailbox
远程设备上运行的应用程序可以调用Relay服务器上的此API来创建一个邮箱,并将安全数据内容(针对配送合作伙伴的加密数据)存储到其中。MailboxIdentifier由Relay服务器创建,作为UUID[RFC4122],使用密码熵生成。在响应中,将返回指向创建的邮箱的URL给调用方。
6.1.1. Endpoint
POST /{version}/m
6.1.2. Request Parameters:
路径参数:
version(字符串,必填)-API的版本。在编写本文档时,为“v1”。
头参数:
deviceAttestation(字符串,可选)-可选的远程OEM设备专有认证数据。
deviceClaim(字符串,UUID,必填)-设备声明(参见术语表)。
6.1.3. Consumes
该API调用通过Content-Type请求头包含以下媒体类型:application/json。
6.1.4. Produces
该API调用通过Content-Type请求头包含以下媒体类型:application/json。
6.1.5. Request body
请求体是一个复杂的结构,包括以下字段:
-
payload(对象,必填)-用于安全凭证传输API,这是一个数据结构,描述特定于凭证提供者的配置信息。它包含以下2个键值对:
- “type”: “AEAD_AES_128_GCM”(参见加密格式部分)。
- “data”: 密文的BASE64编码的二进制值。
-
displayInformation(对象,必填)-用于安全凭证传输API,这是一个数据结构。它允许在接收设备上运行的应用程序构建凭证的可视表示,以展示给用户。数据结构包含以下字段:
- title(字符串,必填)-凭证的标题(例如“Car Key”)。
- description(字符串,必填)-凭证的简要描述(例如“我的个人汽车钥匙”)。
- imageURL(字符串,必填)-指向表示凭证的图片的链接。
-
notificationToken(对象,可选)-可选的通知令牌,用于通知适当的远程设备邮箱数据已更新。数据结构包括以下内容(如果提供notificationToken,则应包括这两个字段):
- type(字符串,必填)-通知令牌名称。用于定义要用于通知适当的远程设备邮箱数据更新的推送通知系统。(例如,APNS的"com.apple.apns")
- tokenData(字符串,必填)-通知令牌数据(根据特定设备OEM通知服务规则编码的数据,例如HEX编码或Base64编码)-应用程序特定-请参阅适当的推送通知系统规范。
-
mailboxConfiguration(对象,可选)-可选的邮箱配置,定义对邮箱的访问权限和邮箱的过期时间。在创建邮箱时需要。OEM设备可以在请求中提供此数据,如果在传入请求中未提供,则Relay服务器将定义默认配置。数据结构包括以下内容:
- accessRights(字符串,可选)-发送方和接收方设备对邮箱的可选访问权限。邮箱的默认访问权限是读取和删除。值定义为以下值的组合:“R” - 读取访问权限,“W” - 写入访问权限,“D” - 删除访问权限。例如:“RD” - 允许从邮箱中读取并删除。
- expiration(字符串,必填)-邮箱的过期时间,格式为"YYYY-MM-DDThh:mm:ssZ"(UTC时区)[RFC3339]。邮箱有限的生存时间。一旦过期,将被删除-参见DeleteMailbox端点。Relay服务器应定期检查过期的邮箱并删除它们。
{
"notificationToken": {
"type":"com.apple.apns",
"tokenData":"APNS1234...QW"
}
}
{
"displayInformation" : {
"title" : "Hotel Pass",
"description" : "Some Hotel Pass",
"imageURL" : "https://example.com/sharingImage"
},
"payload" : {
"type": "AEAD_AES_128_GCM",
"data": "FDEC...987654321"
},
"notificationToken" : {
"type" : "com.apple.apns",
"tokenData" : “APNS...1234"
},
"mailboxConfiguration" : {
"accessRights" : "RWD",
"expiration" : "2022-02-08T14:57:22Z"
}
}
6.1.6. Responses
-
200状态码表示请求成功。响应体中包含以下字段:
-
urlLink(字符串,必需):完整的邮箱链接,包括完全合格的域名和邮箱标识符。详细信息请参考"Share URL"部分。
-
isPushNotificationSupported(布尔值,必需):指示设备是否支持推送通知。设备使用此字段来决定是监听推送主题还是进行长轮询。
示例响应体如下所示:{ "urlLink":"https://relayserver.example.com/m/12345678-9...A-BCD", "isPushNotificationSupported":true }
-
-
201状态码表示已创建。该状态码用于重复的请求(重复的"Mailbox-Request-ID")。如果发现重复的请求,Relay服务器将不会创建新的邮箱,而是响应201状态码。在第一个CreateMailbox请求的头部中传递的"Mailbox-Request-ID"应该由Relay服务器进行存储,并与后续请求中的相同值进行比较,以识别重复的请求。如果找到重复的请求,Relay服务器将不会创建新的邮箱,而是响应201状态码。最后一个成功完成的请求的"Mailbox-Request-ID"值应该根据调用者传递的设备声明进行存储。
-
400状态码表示请求无效。可能是因为无法解析请求或缺少必需的字段。
-
401状态码表示未经授权。调用设备未被授权创建邮箱。例如,设备提供了无效的设备声明或设备认证信息。
6.2. UpdateMailbox
远程设备上运行的应用程序可以调用Relay服务器上的此API来更新现有邮箱中的安全数据内容(特定于供应商的加密数据)。更新操作会覆盖先前存储在邮箱中的安全负载。
6.2.1. Endpoint
PUT /{version}/m/{mailboxIdentifier}
6.2.2. Request Parameters
路径参数:
version(字符串,必需):API的版本。撰写本文档时的版本为"v1"。
mailboxIdentifier(字符串,必需):邮箱标识符(参考术语)。
头部参数:
deviceAttestation(字符串,可选):可选的远程OEM设备专有认证数据。
deviceClaim(字符串,UUID,必需):设备声明(参考术语)。
6.2.3. Consumes
该API调用通过Content-Type请求头包含以下媒体类型:application/json。
6.2.4. Produces
该API调用通过Content-Type请求头包含以下媒体类型:application/json。
6.2.5. Request body
请求体是一个复杂的结构,包括以下字段:
- payload(对象,必需):为了Secure Credential Transfer API的目的,这是一个数据结构,描述特定于Credential Provider的Provisioning信息。它由以下2个键值对组成:
- “type”:“AEAD_AES_128_GCM”(参考加密格式部分)。
- “data”:密文的BASE64编码二进制值。
- notificationToken(对象,可选):用于通知适当的远程设备邮箱数据已更新的可选通知令牌。数据结构包括以下内容(如果提供notificationToken,则应包括两个字段):
-
type(字符串,必需):通知令牌名称。用于定义要使用哪个推送通知系统来通知适当的远程设备邮箱数据已更新。(例如,APNS的"com.apple.apns")
-
tokenData(字符串,必需):通知令牌数据(根据特定设备OEM通知服务规则编码的数据,例如HEX编码或Base64编码)-应用程序特定-请参考适当的推送通知系统规范。
{ "payload" : { "type": "AEAD_AES_128_GCM", "data": "FDEC...987654321" }, "notificationToken":{ "type" : "com.apple.apns", "tokenData" : “APNS...1234" } }
-
6.2.6. Responses
响应体:
isPushNotificationSupported(布尔值,必需):指示是否支持推送通知。设备使用此字段来决定是否应该监听推送主题还是进行长轮询。
{
"isPushNotificationSupported":true
}
200状态:“200”(成功)
201状态:“201”(已创建)- 对重复请求(重复的"Mailbox-Request-ID")的响应。中继服务器应该以201的方式响应重复请求,而不执行邮箱更新。在第一个UpdateMailbox请求的头部中传递的"Mailbox-Request-ID"应该由中继服务器存储,并与后续请求中的相同值进行比较,以识别重复请求。如果发现重复请求,中继服务器不应执行邮箱更新,而是以201的方式响应。最后一个成功完成的请求的"Mailbox-Request-ID"的值应该基于调用者传递的设备声明进行存储。
400错误请求 - 传递了无效的请求(无法解析或缺少必需字段)。
401未经授权 - 调用设备未被授权更新邮箱。例如,设备提供了不正确的设备声明。
404未找到 - 未找到具有提供的邮箱标识符的邮箱。
6.3. DeleteMailbox
在远程设备上运行的应用程序可以调用中继服务器上的此API来关闭已经完成使命的现有邮箱。接收器或发送器设备需要提供设备声明(deviceClaim)以关闭邮箱。
6.3.1. Endpoint
DELETE /{version}/m/{mailboxIdentifier}
6.3.2. Request Parameters
路径参数:
版本(String,必需)- API的版本。在编写本文档时,为"v1"。
mailboxIdentifier(String,必需)- 邮箱标识符(参见术语表)。
头参数:
deviceAttestation(String,可选)- 可选的远程OEM设备专有证明数据。
deviceClaim(String,UUID,必需)- 设备声明(参见术语表)
6.3.3. Responses
200状态:“200”(成功)
401未经授权 - 调用设备未被授权删除邮箱。例如,设备提供了不正确的设备声明。
404未找到 - 未找到具有提供的邮箱标识符的邮箱。如果调用者传递的邮箱标识符无效或邮箱已经被删除(由于重复的DeleteMailbox请求),中继服务器可能会以404的方式响应。
6.4. ReadDisplayInformationFromMailbox
在远程设备上运行的应用程序可以调用中继服务器上的此API来从邮箱中检索公共显示信息内容。显示信息应以OpenGraph格式返回(请参阅https://ogp.me了解详情)。需要以OpenGraph格式显示的显示信息,以便在消息应用程序(例如iMessage或WhatsApp)中显示凭据预览。
6.4.1. Endpoint
GET /{version}/m/{mailboxIdentifier}
6.4.2. Request Parameters
路径参数:
版本(String,必需)- API的版本。在编写本文档时,为"v1"。
mailboxIdentifier(String,必需)- 邮箱标识符(参见术语表)。
6.4.3. Produces
This API call produces the following media types via the Content-Type response header: text/html
6.4.4. Responses
200状态:“200”(成功)
响应体:
- displayInformation(Object,必需)- 以OpenGraph格式呈现的数字凭据的可视化表示(请参阅https://ogp.me了解详情)。
"<html prefix="og: https://ogp.me/ns#">
<head>
<title>Hotel Pass</title>
<meta property="og:title" content="Hotel Pass" />
<meta property="og:type" content="image/jpeg" />
<meta property="og:description" content="Some Hotel Pass" />
<meta property="og:url" content="share://" />
<meta property="og:image" content="https://example.com/photos/photo.jpg" />
<meta property="og:image:width" content="612" />
<meta property="og:image:height" content="408" /></head>
</html>"
图12:读取显示信息响应示例
404未找到 - 未找到具有提供的邮箱标识符的邮箱。
6.5. ReadSecureContentFromMailbox
在远程设备上运行的应用程序可以调用中继服务器上的此API来从邮箱中检索安全有效载荷内容(特定于供应信息提供者的加密数据).
6.5.1. Endpoint
POST /{version}/m/{mailboxIdentifier}
6.5.2. Request Parameters
-
路径参数:
-
版本(String,必需)- API的版本。在编写本文档时,为"v1"。
-
mailboxIdentifier(String,必需)- 邮箱标识符(参见术语表)。
-
-
头参数:
-
deviceAttestation(String,可选)- 可选的远程OEM设备专有证明数据。
-
deviceClaim(String,UUID,必需)- 设备声明(请参见术语表)。
-
6.5.3. Produces
This API call produces the following media types via the Content-Type response header: application/json
6.5.4. Responses
200状态:“200”(成功)
响应体:
-
payload(String,必需)- 用于安全凭据传输API的目的,这是一个描述特定于凭据提供者的供应信息的JSON元数据块。
-
displayInformation(Object,必需)- 用于安全凭据传输API的目的,这是一个JSON数据块。它允许在接收设备上运行的应用程序构建凭据的可视化表示以显示给用户。特定于凭据提供者。
-
expiration(String,必需)- 邮箱将过期的日期。邮箱的过期时间在创建邮箱时设置。过期时间应为完整的[RFC3339]日期字符串,格式为"YYYY-MM-DDThh:mm:ssZ"(UTC时区),可用于允许接收客户端显示共享何时过期。
{
“displayInformation" : {
"title" : "Hotel Pass",
"description" : "Some Hotel Pass",
"imageURL" : "https://example.com/sharingImage"
},
"payload" : {
"type": "AEAD_AES_128_GCM",
"data": "FDEC...987654321"
},
"expiration": "2021-11-03T20:32:34Z"
}
401未经授权 - 调用设备未被授权读取邮箱的安全内容。例如,设备提供了错误的设备声明。
404未找到 - 未找到具有提供的邮箱标识符的邮箱。
6.6. RelinquishMailbox
在远程设备上运行的应用程序可以调用中继服务器上的此API来放弃对邮箱的所有权。接收设备需要提供当前已建立的接收者设备声明,以放弃对邮箱的所有权。一旦放弃,邮箱可以绑定到另一个接收设备,该设备在ReadSecureContentFromMailbox调用中提供其设备声明。
6.6.1. Endpoint
PATCH /{version}/m/{mailboxIdentifier}
6.6.2. Request Parameters
-
路径参数:
-
版本(String,必需)- API的版本。在编写本文档时,为"v1"。
-
mailboxIdentifier(String,必需)- 邮箱标识符(参见术语表)。
-
-
头参数:
-
deviceAttestation(String,可选)- 可选的远程OEM设备专有证明数据。
-
deviceClaim(String,UUID,必需)- 设备声明(请参见术语表)。
-
6.6.3. Responses
200状态:“200”(成功)
201状态:“201”(已创建) - 对重复请求(重复的"Mailbox-Request-ID")的响应。中继服务器应该以201响应重复请求,而不执行邮箱放弃操作。中继服务器应该存储第一个RelinquishMailbox请求头中传递的"Mailbox-Request-ID",并将其与后续请求中的相同值进行比较,以识别重复请求。如果找到重复请求,中继服务器不应执行邮箱放弃操作,而是以201进行响应。最后一个成功完成的请求的"Mailbox-Request-ID"的值应根据调用方传递的设备声明进行存储。
401未经授权 - 调用设备未被授权放弃邮箱。例如,设备提供了错误的设备声明,或者设备未绑定到该邮箱。
404未找到 - 未找到具有提供的邮箱标识符的邮箱。如果调用方传递的邮箱标识符无效,中继服务器可以以404进行响应。
7. Security Considerations
考虑了以下威胁和缓解措施:
-
发送方与错误的接收方共享
- 应该鼓励发送方通过允许接收方进行身份验证的渠道(例如语音)共享Secret。
- 配置合作伙伴应该允许发送方取消现有的共享。
-
恶意接收方将共享转发给第三方而不赎回它,或接收方的设备被攻破。
- 没有缓解措施,发送方应该只与他们信任的接收方共享。
-
恶意接收方尝试重复使用共享
- 配置合作伙伴应该确保共享的配置信息只能被兑换一次。
-
共享URL意外泄露。(例如,共享URL作为消息发送,显示在锁定屏幕上)
- 需要知道Secret才能访问配置信息,并且应该通过单独的渠道发送。
- 需要设备声明(如果发送方和接收方已经都联系过中继服务器)
-
网络攻击
- 中间人攻击:中继服务器应该仅允许TLS连接。向用户显示的URL应该包括https协议。
- MailboxIdentifier猜测:MailboxIdentifier是一个版本4的UUID [RFC4122],应该包含122位密码熵,使得暴力攻击变得不切实际。
-
通过中继服务器预览页面(ReadDisplayInformationFromMailbox)托管恶意或不受信任的脚本的风险
- 中继服务器应该不允许在预览页面上托管第三方JavaScript,或者实施政策并利用工具来维护这些脚本的信任(例如,强制客户端根据其良好已知的哈希验证脚本)。
7.1. Sender/Receiver privacy
- 中继服务器在任何时候都不应存储或跟踪发送方和接收方设备的身份。
- 通知令牌的值不应包含能够识别提供它的设备的信息。它应该对于每个新的共享都是不同的,以防止中继服务器关联不同的共享。
- 通知令牌应该只通知相应的设备与其关联的邮箱上有数据更新(通过设备声明)。每个设备应该跟踪与其关联的所有邮箱,并对适当的邮箱进行读取调用。
- 发送方和接收方设备都应该存储用于进行有效凭据传输的中继服务器的URL。
- DeviceAttestation头参数的值不应包含能够识别提供它的设备的信息。它应该对于每个新的共享都是不同的,以防止中继服务器关联不同的共享。
- 显示信息没有加密,因此,它不应包含任何能够识别发送方或接收方设备的信息。
7.2. Credential’s confidentiality and integrity
- 邮箱的内容只能对拥有Secret的设备可见。
- 建议通过不同的渠道(例如,通过短信发送URL,通过iMessage发送Secret)将URL和Secret从发送方设备发送到接收方设备(即离线发送)。
- 中继服务器在任何时候都不能接收带有MailboxIdentifier的Secret。
- 邮箱的内容必须通过加密校验和(例如,MAC、AES-GCM标签)来保证其完整性。
中继服务器应定期检查并删除已过期的邮箱(参考CreateMailbox请求中的过期参数)。 - 如果发送方设备通过同一渠道发送URL和Secret作为单个URL,则发送方必须将Secret作为URI片段[RFC3986]附加到URL上,以便生成的URL如下所示。接收方设备在收到此类URL后,在调用中继服务器API之前,必须删除片段(即Secret)。
“https://relayserver.example.com/v1/m/{mailboxIdentifier}#{Secret}”
7.3. Second factor authentication for Receiver credential provisioning
- 在凭据提供过程中,Provisioning Partner应要求接收方设备提供额外的安全确认(PIN码)。
- PIN码应由发送方设备在使用Relay Server创建新邮箱时生成,并将其与凭据提供信息一起发送到中继服务器上。
- PIN码应该通过安全方式(最好是加密通道)从发送方设备离线发送给接收方设备,同时还包括邮箱URL和Secret。
- 如果发送方设备无法通过安全通道发送PIN码,则可以将其包含在存储在中继服务器上的加密有效负载中,以便接收方设备可以解密并用于从凭据提供者获取凭据提供信息。
- 在接收方设备调用凭据提供者以获取凭据提供信息时,凭据提供者应限制PIN码输入尝试的次数。
- PIN码在发送方设备和接收方设备之间传输的方式由具体实现定义,超出了本文档的范围。
8. IANA Considerations
此文档在“永久消息头字段名称”https://www.iana.org/assignments/message-headers中注册了一个新的标题,“Mailbox-Request-ID”。
+--------------------+----------+--------+---------------+
| Header Field Name | Protocol | Status | Reference |
+--------------------+----------+--------+---------------+
| Mailbox-Request-ID | http | std | This document |
+--------------------+----------+--------+---------------+