JOSESwift 是一个模块化和可扩展的框架,用于 Swift 中编写的 JOSE 标准 JWS、JWE 和 JWK。
💡 请注意,此 JOSE 标准的实现尚未完全完成。 例如,目前仅提供有限的支持算法集。 此外,我们目前仅支持 JOSE 类型的紧凑序列化。 如果您缺少特定的功能、算法或序列化,请随时提交 pull request。
如果您缺少特定的功能、算法或序列化,请随时提交 pull request。
🔏 JWS | 🔐 JWE | 🔑 JWK | |||||||
---|---|---|---|---|---|---|---|---|---|
数字签名和 MAC | 密钥管理 | 内容加密 | 密钥 | ||||||
HS256 |
✅ | RSA1_5 |
✅ | A128CBC-HS256 |
✅ | RSA |
✅ | ||
HS384 |
✅ | RSA-OAEP |
✅ | A192CBC-HS384 |
✅ | EC |
✅ | ||
HS512 |
✅ | RSA-OAEP-256 |
✅ | A256CBC-HS512 |
✅ | oct |
✅ | ||
RS256 |
✅ | A128KW |
✅ | A128GCM |
✅ | ||||
RS384 |
✅ | A192KW |
✅ | A192GCM |
✅ | ||||
RS512 |
✅ | A256KW |
✅ | A256GCM |
✅ | ||||
ES256 |
✅ | dir |
✅ | ||||||
ES384 |
✅ | ECDH-ES |
✅ | ||||||
ES512 |
✅ | ECDH-ES+A128KW |
✅ | ||||||
PS256 |
✅ | ECDH-ES+A192KW |
✅ | ||||||
PS384 |
✅ | ECDH-ES+A256KW |
✅ | ||||||
PS512 |
✅ | A128GCMKW |
|||||||
A192GCMKW |
|||||||||
A256GCMKW |
|||||||||
PBES2-HS256+A128KW |
✅ | ||||||||
PBES2-HS384+A192KW |
✅ | ||||||||
PBES2-HS512+A256KW |
✅ |
为了实现互换性,JOSESwift 目前支持 JWS 和 JWE 的紧凑序列化。
紧凑序列化 | JSON 序列化 |
---|---|
✅ |
JOSESwift 支持 DEFLATE 压缩算法 用于 JWE。
JOSESwift 可以很好地集成到您的 iOS 和 macOS 项目中。 我们支持以下包管理器
要将 JOSESwift 集成到您的 Xcode 项目中,请将其包含在您的 Podfile
中
source 'https://cdn.cocoapods.org/'
platform :ios, '13.0'
use_frameworks!
target '<Your Target Name>' do
pod 'JOSESwift', '~> 3.0'
end
然后通过运行 pod install
安装它。 有关使用 CocoaPods 的更多文档可以在这里找到。
要将 JOSESwift 集成到您的 Xcode 项目中,请将其包含在您的 Cartfile
中
github "airsidemobile/JOSESwift" ~> 3.0
然后通过运行 carthage update
构建它,并将构建的框架拖到您的 Xcode 项目中。 有关使用 Carthage 的更多文档可以在这里找到。
要将 JOSESwift 作为 Swift 包集成到您的 Xcode 项目中,请按照 Apple 关于如何将包依赖项添加到您的应用程序的文章进行操作。
或者,当手动使用 Swift Package Manager 时,请在您的 Package.swift
文件中包含以下依赖项。 有关指定依赖项版本要求的更多详细信息,请参阅Apple 的文档。
.package(url: "https://github.com/airsidemobile/JOSESwift.git", from: "3.0.0")
JOSESwift 涵盖三个功能方面
JWS
使用数字签名封装并保护数据,接收 JWS
的人可以验证该签名。
为了构造 JWS,我们需要提供以下部分
var header = JWSHeader(algorithm: .RS512)
您可以通过方便的访问器设置注册的标头参数
header.kid = "2018-10-08"
header.typ = "JWS"
try header.set("rice", forParameter: "meal")
let meal = header.get(parameter: "meal") // "rice"
header.remove(parameter: "meal")
let message = "Summer ⛱, Sun ☀️, Cactus 🌵".data(using: .utf8)!
let payload = Payload(message)
签名者算法必须与标头算法匹配。
let privateKey: SecKey = /* ... */
let signer = Signer(signatureAlgorithm: .RS512, key: privateKey)!
JWS 紧凑序列化是一个 URL 安全的字符串,可以使用您选择的方法轻松地传输给第三方。
guard let jws = try? JWS(header: header, payload: payload, signer: signer) else { ... }
print(jws.compactSerializedString) // ey (...) J9.U3 (...) LU.na (...) 1A
有关构建 JWS 的更多详细信息,请参见wiki。
let publicKey: SecKey = /* ... */
let serialization = "ey (..) n0.HK (..) pQ.yS (..) PA.AK (..) Jx.hB (..) 7w"
do {
let jws = try JWS(compactSerialization: serialization)
let verifier = Verifier(verifyingAlgorithm: .RS512, publicKey: publicKey)!
let payload = try jws.validate(using: verifier).payload
let message = String(data: payload.data(), encoding: .utf8)!
print(message) // Summer ⛱, Sun ☀️, Cactus 🌵
}
有关验证现有序列化的 JWS 的更多详细信息,请参见wiki。
JWE 通过加密封装和保护数据。 它可以通过 JWE 的接收者解密。
为了构造 JWE,我们需要提供以下部分
var header = JWEHeader(keyManagementAlgorithm: .RSA1_5, contentEncryptionAlgorithm: .A256CBCHS512)
您可以设置注册的标头参数
header.kid = "2018-10-08"
header.typ = "JWE"
try header.set("rice", forParameter: "meal")
let meal = header.get(parameter: "meal") // "rice"
header.remove(parameter: "meal")
let message = "Summer ⛱, Sun ☀️, Cactus 🌵".data(using: .utf8)!
let payload = Payload(message)
加密器算法必须与标头算法匹配。
let publicKey: SecKey = /* ... */
let encrypter = Encrypter(keyManagementAlgorithm: .RSA1_5, contentEncryptionAlgorithm: .A256CBCHS512, encryptionKey: publicKey)!
请注意,提供的加密密钥的类型必须与指定的密钥管理算法匹配,如下表所示。
密钥管理算法 | 加密密钥类型 |
---|---|
RSA1_5 | SecKey |
RSAOAEP | SecKey |
RSAOAEP256 | SecKey |
A128KW | 数据 |
A192KW | 数据 |
A256KW | 数据 |
direct | 数据 |
JWE 紧凑序列化是一个 URL 安全的字符串,可以使用您选择的方法轻松地传输给第三方。
guard let jwe = try? JWE(header: header, payload: payload, encrypter: encrypter) else { ... }
print(jwe.compactSerializedString) // ey (..) n0.HK (..) pQ.yS (..) PA.AK (..) Jx.hB (..) 7w
有关构建 JWE 的更多详细信息,请参见wiki。
let privateKey: SecKey = /* ... */
let serialization = "ey (..) n0.HK (..) pQ.yS (..) PA.AK (..) Jx.hB (..) 7w"
do {
let jwe = try JWE(compactSerialization: serialization)
let decrypter = Decrypter(keyManagementAlgorithm: .RSA1_5, contentEncryptionAlgorithm: .A256CBCHS512, decryptionKey: privateKey)!
let payload = try jwe.decrypt(using: decrypter)
let message = String(data: payload.data(), encoding: .utf8)!
print(message) // Summer ⛱, Sun ☀️, Cactus 🌵
}
有关解密现有序列化的 JWE 的更多详细信息,请参见wiki。
请注意,提供的解密密钥的类型必须与指定的密钥管理算法匹配,如下表所示。
密钥管理算法 | 解密密钥类型 |
---|---|
RSA1_5 | SecKey |
RSAOAEP | SecKey |
RSAOAEP256 | SecKey |
A128KW | 数据 |
A192KW | 数据 |
A256KW | 数据 |
direct | 数据 |
JWK 是一种 JSON 数据结构,表示加密密钥。 例如,您可以将其用作 JWS 或 JWE 的有效负载,以将您的公钥传输到服务器。
let publicKey: SecKey = /* ... */
let jwk = try! RSAPublicKey(publicKey: publicKey)
let json = jwk.jsonString()! // {"kty":"RSA","n":"MHZ4L...uS2d3","e":"QVFBQg"}
有关编码 RSA 公钥的更多详细信息,请参见wiki。
let json: Data = /* ... */
let jwk = try! RSAPublicKey(data: json)
let publicKey: SecKey = try! jwk.converted(to: SecKey.self)
有关解码 RSA 公钥的更多详细信息,请参见wiki。
"key_ops"
和 "x5c"
。 这是由于我们的解码实现中的一个错误。 有关详细信息,请参见#117。
JOSESwift 使用 Apple 的 Security framework、Apple 的 CommonCrypto 和 Apple 的 CryptoKit 进行加密。
对于安全披露或相关事宜,请联系joseswift@airsidemobile.com。
有关更多信息,请参见我们的安全策略。
鼓励并非常欢迎为该项目做出贡献。 🤓
如果您想做出贡献,请提交 pull request。 对于功能请求、讨论或错误报告,只需打开一个 issue。
有关更多信息,请参见我们的贡献指南。
您可以在相应的 RFC 中找到有关相关 JOSE 标准的详细信息
不要忘记查看我们的 wiki 以获取更详细的文档。
请随时通过joseswift@airsidemobile.com与项目维护者联系。
JOSESwift 由 Airside Mobile 维护。
该徽标由 Ivan Leuzzi 设计。
感谢以下项目,它们在开发过程中为我们提供了参考和灵感
JOSESwift 在 Apache License 2.0 下获得许可。 有关详细信息,请参见LICENSE。