在 Swift 中引入不经意的 HTTP 支持
我们很高兴在 Swift 生态系统中引入对不经意的 HTTP 的临时支持实现,并发布一个名为 SwiftNIO Oblivious HTTP 的新软件包。
不经意的 HTTP 是一种协议,允许客户端向服务器发出请求,而服务器无法识别这些请求的来源。传统的 HTTP 请求可能会泄露关于客户端的身份信息,例如源 IP 地址,并可能允许将来自同一客户端的多个请求识别为源自同一节点。相比之下,不经意的 HTTP 提供了一种安全机制来保护识别客户端信息,通过将 HTTP 消息加密与受信任的第三方中继服务相结合来实现,从而在不产生显著性能开销的情况下提高用户的隐私。
不经意的 HTTP 是一项至关重要的基础技术,它支持一系列新兴的隐私保护网络技术,包括增强 DNS 隐私 的提案。在 Apple,我们也正在使用它,通过 私有云计算 将 Apple 设备行业领先的隐私保护扩展到云端。不经意的 HTTP 帮助确保处理请求的设备永远无法获得关于请求来源的个人身份数据。它还可以加强系统,防止针对个人数据请求的攻击。
SwiftNIO Oblivious HTTP
我们今天发布的软件包仍处于积极开发阶段,并且是 SwiftNIO 项目 的一部分,用于开发可维护的高性能网络代码。它支持两个独立的标准
这两个实现可以一起使用或单独使用;它们使 Swift 客户端 能够使用依赖于不经意的 HTTP 的服务,并使 Swift 服务器 能够实现该规范。
该软件包本身分为两个库
- 主库
OblivousHTTP
提供了实现不经意的 HTTP 所需的 RFC 9292 中的二进制 HTTP 编码方案,以及该方案与 SwiftNIO 的绑定。 - 第二个库
OblivousX
提供了更通用的 API,这些 API 构成了不经意的 HTTP 使用的加密方案的基础,但也可以应用于您选择的其他编码。
二进制 HTTP 编码
RFC 9292 中的二进制 HTTP 表示形式定义了一种机制,用于序列化和反序列化不依赖于特定线路格式(例如 HTTP/1.1 或 HTTP/2)的抽象 HTTP 消息。SwiftNIO Oblivious HTTP 提供了非常简单的序列化和反序列化 API。以下是如何使用 API 进行序列化和反序列化的示例
import ObliviousHTTP
import NIOCore
import NIOHTTP1
let serializer = BHTTPSerializer()
var buffer = ByteBuffer()
serializer.serialize(.request(.head(.init(method: .GET))), into: &buffer)
serializer.serialize(.request(.body(payload)), into: &buffer)
serializer.serialize(.request(.end(nil)), into: &buffer)
var parser = BHTTPParser(role: .server)
parser.append(buffer)
parser.completeBodyReceived()
while let message = try parser.nextMessage() {
print(message)
}
不经意的封装
不经意的 HTTP 规范将 HTTP 的二进制序列化格式与基于 混合公钥加密 (HPKE) 构建的加密方案相结合。这种加密方案是完全通用的,因此除了二进制 HTTP 消息之外,它还可以用于任何任意数据。
ObliviousX
库提供了一整套用于处理此封装方案的 API。它们有两种风格:单次函数,实现了 RFC 9457 中的 OHTTP 方案,以及流式风格,实现了 草案分块 OHTTP 规范 中定义的方案。以下是单次 API 用法的一个示例
import ObliviousX
// Encryption
let message = Data("Hello, this is my secret message".utf8)
let (encapsulatedRequest, sender) = OHTTPEncapsulation.encapsulateRequest(
keyID: serverKeyID,
publicKey: serverPublicKey,
ciphersuite: .P256_SHA256_AES_GCM_256,
mediaType: "text/plain",
content: message
)
// Decryption
let (header, consumedBytes) = OHTTPEncapsulation.parseRequestHeader(
encapsulatedRequest: encapsulatedRequest
)
assert(header.keyID == serverKeyID)
assert(header.kem == .P256_HKDF_SHA256)
assert(header.kdf == .HKDF_SHA256)
assert(header.aead == .AES_GCM_256)
let decapsulator = OHTTPEncapsulation.RequestDecapsulator(
requestHeader: header,
message: encapsulatedRequest.dropFirst(consumedBytes)
)
let (deEncapsulated, context) = try decapsulator.decapsulate(
mediaType: "text/plain",
privateKey: serverPrivateKey
)
assert(deEncapsulated == message)
下一步是什么
此软件包在早期开发阶段发布,旨在征求反馈和贡献。您可以访问 GitHub 上的 SwiftNIO Oblivious HTTP 库 开始使用,并加入我们的 Swift 论坛 讨论该库并提出改进建议。
虽然核心加密方案被认为运行良好,但我们仍在完成二进制 HTTP 和不经意的 HTTP 的完整绑定设计工作。此外,以下项目已列入我们的路线图
- 以可以放入 ChannelPipeline 的 ChannelHandlers 形式,生成与 SwiftNIO 更好的绑定。
- 生成使用 swift-http-types 而不是 SwiftNIO 类型的 BinaryHTTP 版本,以便更好地与 Swift 生态系统的其余部分组合,并有可能消除对 SwiftNIO 的依赖。
- 在 IETF 最终确定草案后,最终支持分块不经意的 HTTP。
- 其他 API 调整以支持更广泛的用例。
我们欢迎在此设计过程阶段的社区反馈,以及拉取请求和 issue 形式的贡献,我们将努力在未来几个月内改进支持,并为现代互联网的基础设施提供更强大的隐私保护。