隆重推出 Swift Crypto
我很高兴地宣布 Swift 生态系统的一个新的开源项目:Swift Crypto。Swift Crypto 是一个新的 Swift 软件包,它将 Apple CryptoKit 出色的 API 带给更广泛的 Swift 社区。这将允许 Swift 开发者,无论他们在哪个平台上部署应用程序,都能访问这些 API 以进行一组通用的加密操作。
这个新的库为在 Swift 支持的所有平台上使用 CryptoKit API 提供了跨平台解决方案。这意味着在 Swift 支持的所有平台上,您现在都可以简单地编写以下代码来获取所有 CryptoKit API
import Crypto
在 Apple 平台上,Swift Crypto 直接引用 CryptoKit,而在所有其他平台上,它使用基于 BoringSSL 库构建的全新实现。这为 Swift 用户提供了在所有平台上轻松访问一套易于使用、安全的加密 API 的途径,并且是在编写跨平台加密代码时非常有用的工具。
示例
Swift Crypto 使许多强大的功能变得非常容易。例如,使用 AES GCM 的安全身份验证加密,既可以隐藏您的数据,又可以抵抗攻击者尝试修改数据,就像下面这样简单:
func encrypt(input: [UInt8]) throws -> Data {
// Don't forget to save your key somewhere!
let key = SymmetricKey(size: .bits256)
let sealedBox = try AES.GCM.seal(input, using: key)
return sealedBox.combined!
}
这段代码避免了您在自行构建加密方案时可能遇到的许多陷阱。例如,它确保您使用随机选择的 nonce,并对您的密文进行身份验证。这两者都可以防止系统受到各种攻击,但在许多其他加密库中,这两者不一定是自动的。
同样,生成消息身份验证码也很简单,您可以使用它来确保数据没有被篡改
func authenticate(message: [UInt8]) -> [UInt8] {
// Again, don't forget to save your keys!
let key = SymmetricKey(size: .bits256)
return Array(HMAC<SHA256>.authenticationCode(for: message, using: key))
}
甚至执行椭圆曲线密钥交换的相当复杂的逻辑也包含在 Swift Crypto 中。例如,使用 Curve25519 生成共享密钥
func curve25519SharedSecret(myKey: Curve25519.KeyAgreement.PrivateKey, theirKeyBytes: [UInt8]) throws -> SharedSecret {
let theirKey = try Curve25519.KeyAgreement.PublicKey(rawRepresentation: theirKeyBytes)
return try myKey.sharedSecretFromKeyAgreement(with: theirKey)
}
这些简单而强大的 API 的最终结果是,您现在几乎可以用零代码构建安全的跨平台加密方案,而且无需太多专业知识。
有关 Apple CryptoKit 的更多详细信息,请参阅 WWDC 2019 的“Cryptography and Your Apps”会话 和 项目文档。在本文的其余部分,我将讨论 Swift Crypto 为生态系统带来了什么,以及用户在使用该项目时应该注意什么。
什么是 Swift Crypto?
Swift Crypto 的核心是一个非常简单的想法,由两部分组成
-
来自 Apple CryptoKit 的 API,以开源软件许可证发布在一个库中。
-
使用 Google 的 BoringSSL 作为加密原语的底层实现,对这些 API 进行完整的全新实现。
然而,在这些简单的想法背后,却隐藏着许多非常复杂的实现问题。第一个问题是关于硬件。虽然 Apple CryptoKit 的大部分是对众所周知的加密原语的直接实现,但 API 的一部分是围绕使用 Apple 的安全 Enclave 处理器来安全地存储和计算密钥材料而构建的。Apple 的安全 Enclave 处理器在非 Apple 硬件上不可用:因此,Swift Crypto 不提供这些 API。
第二个问题涵盖了软件分发模型。为了让开发者在非 Apple 平台上使用 Swift Crypto 时更容易更新它,我们利用 Swift Package Manager 来分发 Swift Crypto。这允许用户通过简单的 swift package update
来拉取安全修复程序和 API 更新。
第三个问题是关于兼容性。至关重要的是,用户可以信任他们从 Swift Crypto 获得的结果与他们从 Apple CryptoKit 获得的结果相同。当使用 Swift Crypto 和使用 Apple CryptoKit 时,相同的输入到相同的 API 产生语义上不同的结果是完全不可接受的。为此,我们还安排了一个共享的测试套件,以确保 Swift Crypto 和 Apple CryptoKit 都必须满足此标准。
在某些情况下,这需要额外的工作,相当微妙,以弥合 Apple CryptoKit 所需的验证与 BoringSSL 完成的验证之间的不匹配。在一两种情况下,这也需要对某些算法进行全新的实现。这将继续是该项目未来工作的大部分,但我们认为至关重要的是,要确保用户可以期望 Apple CryptoKit 提供的所有功能都尽可能在 Swift Crypto 中可用。
鉴于我们必须做这些额外的工作,那么拥有两个后端而不是将 CryptoKit 和 Swift Crypto 合并到一个后端有什么优势呢?主要的优势是验证。通过 CryptoKit API 的两个独立实现,我们能够相互测试这些实现以及它们自己的测试套件。这提高了两个实现的可靠性和兼容性,减少了回归的可能性,并且通过比较两个实现的输出来轻松识别错误。
该项目的最终结果是一个可以在 Swift 支持的任何地方安装的软件包,它为您提供的平台提供最佳的实现,并且使在 Swift 中编写安全的跨平台或服务器端应用程序变得更加容易。
Swift Crypto 是一个语义版本化的 Swift 软件包,并根据 Apache 2.0 许可证提供。这使得它在任何地方都易于使用且可靠。
Swift Crypto 的演进
由于 Swift Crypto 的核心目标是为在更广泛的平台上使用 Apple CryptoKit 的 API 提供跨平台解决方案,因此 API 自然会遵循 Apple CryptoKit 本身的发展。但是,由于 Swift Crypto 是一个开源项目,因此在 Swift Crypto 中直接提出 API 是有一定范围的。根据这些 API 的范围,它们也可能被考虑在 Apple CryptoKit 中并行实现。
除了需要专用硬件的 API 之外,在 Apple CryptoKit API 实现可用的情况下,Swift Crypto 将始终使用它,但是当这样的 API 不可用时,可以使用基于 Swift Crypto 的实现。核心 API 将与 Apple CryptoKit 同步发展,我们的测试套件与 Apple CryptoKit 共享,确保两个项目都必须通过彼此的 API 测试套件,从而确保 Swift Crypto 和 Apple CryptoKit 将完全兼容。
但是请注意,Swift Crypto 的一个重要的设计原则是,支持所有加密原语并非明确目标。支持许多原语的风险在于,用户更难做出选择,尤其是安全的选择。如果您考虑提出新的 API 表面,请注意这一点:某些原语可能不受支持,因为该项目已经有使用更广泛部署或更安全的替代方案的等效原语。
参与进来!
如果您对 Swift Crypto 的任何方面感兴趣,请参与进来!源代码可用,我们鼓励来自开源社区的贡献。如果您有疑问或想讨论 Swift Crypto,请随时在 Swift 论坛上聊天。如果您想报告错误,请使用 GitHub 问题跟踪器。我们期待与您合作,共同推动行业朝着更好、更安全的编程未来迈进。