JOSESwift


JOSESwift 是一个模块化和可扩展的框架,用于 Swift 中编写的 JOSE 标准 JWSJWEJWK

CircleCI

💡 请注意,此 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 目前支持 JWSJWE 的紧凑序列化。

紧凑序列化 JSON 序列化

压缩算法

JOSESwift 支持 DEFLATE 压缩算法,用于 JWE

安装

JOSESwift 可以很好地集成到您的 iOS 和 macOS 项目中。我们支持以下包管理器

CocoaPods

要将 JOSESwift 集成到您的 Xcode 项目中,请将其包含在您的 Podfile

source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '10.0'
use_frameworks!

target '<Your Target Name>' do
    pod 'JOSESwift', '~> 2.3'
end

然后运行 pod install 安装它。有关使用 CocoaPods 的更多文档,请访问 此处

Carthage

要将 JOSESwift 集成到您的 Xcode 项目中,请将其包含在您的 Cartfile

github "airsidemobile/JOSESwift" ~> 2.3

然后运行 carthage update 构建它,并将构建的框架拖到您的 Xcode 项目中。有关使用 Carthage 的更多文档,请访问 此处

Swift Package Manager

要将 JOSESwift 作为 Swift 包集成到您的 Xcode 项目中,请按照 Apple 的文章了解如何将包依赖项添加到您的应用程序

或者,当手动使用 Swift Package Manager 时,请在您的 Package.swift 文件中包含以下依赖项。有关指定依赖项版本要求的更多详细信息,请参阅Apple 的文档

.package(url: "https://github.com/airsidemobile/JOSESwift.git", from: "2.3.0")

用法

JOSESwift 涵盖三个功能方面

  1. JWS:数字签名
  2. JWE:加密和解密
  3. JWK:表示密钥

JWS:数字签名

JWS 封装并使用数字签名保护数据,该签名可以由 JWS 的接收者验证。

签名数据

为了构造 JWS,我们需要提供以下部分

  1. 标头
  2. 载荷
  3. 签名者
标头
let header = JWSHeader(algorithm: .RS512)

您可以选择设置附加参数

header.kid = "2018-10-08"

header.typ = "JWS"
载荷
let message = "Summer ⛱, Sun ☀️, Cactus 🌵".data(using: .utf8)!

let payload = Payload(message)
签名者

签名者算法必须与标头算法匹配。

let privateKey: SecKey = /* ... */

let signer = Signer(signingAlgorithm: .RS512, privateKey: 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 的接收者解密。

加密数据

为了构造 JWE,我们需要提供以下部分

  1. 标头
  2. 载荷
  3. 加密器
标头
let header = JWEHeader(keyManagementAlgorithm: .RSA1_5, contentEncryptionAlgorithm: .A256CBCHS512)

您可以选择设置附加参数

header.kid = "2018-10-08"

header.typ = "JWE"
载荷
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 Data
A192KW Data
A256KW Data
direct Data
序列化

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 Data
A192KW Data
A256KW Data
direct Data

JWK:表示密钥

JWK 是一个 JSON 数据结构,表示一个加密密钥。例如,您可以将其用作 JWS 或 JWE 的载荷,以将您的公钥传输到服务器。

编码 RSA 公钥

let publicKey: SecKey = /* ... */

let jwk = try! RSAPublicKey(publicKey: publicKey)

let json = jwk.jsonString()! // {"kty":"RSA","n":"MHZ4L...uS2d3","e":"QVFBQg"}

有关编码 RSA 公钥的更多详细信息,请访问 wiki

解码 RSA 公钥

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 frameworkApple 的 CommonCrypto 进行加密。

对于安全漏洞披露或相关事宜,请联系 joseswift@airsidemobile.com

有关更多信息,请参阅我们的安全策略

贡献

我们鼓励并非常欢迎对项目做出贡献。 🤓

如果您想贡献代码,请提交 pull request。对于功能请求、讨论或错误报告,请直接开启 issue。

有关更多信息,请参阅我们的贡献指南

资源

您可以在相应的 RFC 中找到有关相关 JOSE 标准的详细信息

不要忘记查看我们的 wiki 以获取更详细的文档。

联系方式

请随时通过 joseswift@airsidemobile.com 联系项目维护者。

致谢

JOSESwift 由 Airside Mobile 维护。

项目作者和维护者

@carol-mohemian, @daniel-mohemian, @gigi-mohemian

审阅者

@haeser, @michael-mohemian

Logo

Logo 由 Ivan Leuzzi 设计。

感谢

感谢以下项目,它们在开发过程中为我们提供了参考和灵感

许可证

JOSESwift 在 Apache License 2.0 许可下发布。有关详细信息,请参阅 LICENSE