Screenshot

Jose Swift 库

Swift Swift6 iOS MacOS WatchOS TvOS

此库为 Jose 系列标准提供全面的支持,包括 JWA(JSON Web 算法)、JWK(JSON Web 密钥)、JWE(JSON Web 加密)、JWS(JSON Web 签名)和 JWT(JSON Web 令牌)。这些标准是现代 Web 安全协议不可或缺的一部分,为不同方之间提供安全的密钥管理、数据加密、签名和声明表示方法。

目录

  1. 可用特性和算法
  2. 要求
  3. Swift Package Manager (SPM)
  4. 文档
  5. 模块
  6. 贡献
  7. 参考
  8. 致谢
  9. 许可证

可用特性和算法

JWT

JWT 支持的算法 JWT 支持的类型 JWT 支持的声明验证
算法 支持
所有 JWE 算法
所有 JWS 算法
类型 支持
已签名
已加密
嵌套签名
嵌套加密
声明 支持
iss
sub
aud
nbf
exp
iat
typ
cty
DSL 声明构建器

JWE

JWE 支持的类型 JWE 支持的算法 JWE 支持的编码
类型 支持
紧凑字符串
JSON
JSON 扁平化
算法 支持
RSA1_5
RSA-OAEP
RSA-OAEP-256
A128KW
A192KW
A256KW
DIRECT
ECDH-ES
ECDH-ES+A128KW
ECDH-ES+A192KW
ECDH-ES+A256KW
ECDH-1PU
ECDH-1PU+A128KW
ECDH-1PU+A192KW
ECDH-1PU+A256KW
A128GCMKW
A192GCMKW
A256GCMKW
PBES2-HS256+A128KW
PBES2-HS384+A192KW
PBES2-HS512+A256KW
编码算法 支持
A128CBC-HS256
A128CBC-HS384
A128CBC-HS512
A128GCMKW
A192GCMKW
A256GCMKW
C20P
XC20P

JWS

JWS 支持的类型 JWS 支持的算法
类型 支持
紧凑字符串
JSON
JSON 扁平化
未编码的 Payload*
算法 支持
HS256
HS384
HS512
RS256
RS384
RS512
ES256
ES256K
ES384
ES512
PS256
PS384
PS512
EdDSA

注意:JWS 未编码的 payload 参见 RFC-7797

JWK

JWK 支持的密钥类型
密钥类型 支持
EC
RSA
OKT
OCK

要求

Swift Package Manager (SPM)

要在您的项目中使用 jose-swift 包,您需要在您的 Package.swift 文件中将其添加为依赖。

步骤 1:添加依赖

打开您的 Package.swift 文件,并将 jose-swift 包添加到您的 dependencies 数组中。 请务必指定您要使用的版本。

dependencies: [
    .package(url: "https://github.com/beatt83/jose-swift.git", .upToNextMinor(from: "2.4.0")),
    // ... other dependencies ...
]

步骤 2:添加目标依赖

在同一个 Package.swift 文件中,将 jose-swift 添加到您的目标的依赖项中

targets: [
    .target(
        name: "YourTargetName",
        dependencies: [
            "jose-swift",
            // ... other dependencies ...
        ]
    ),
    // ... other targets ...
]

步骤 3:在您的项目中导入和使用

一旦您将该包添加为依赖项,您就可以在您的 Swift 文件中导入 JSONWebEncryption、JWS、JWA 或 JWK,具体取决于您需要的功能。

import JSONWebEncryption
// or
import JSONWebSignature
// or
import JSONWebAlgorithms
// or
import JSONWebKey
// or
import JSONWebToken

文档

您可以访问 这里 获取文档。

入门指南

有关如何使用该库的快速指南,请访问入门指南教程。

有关如何使用此库的更多示例,请尝试检查单元测试,它们是详尽的,应该提供更多信息。

模块

JWK (JSON Web Key)

JWK 是一种以 JSON 格式表示加密密钥的标准方法,如 RFC 7517 中所定义。 此模块提供用于生成、解析和管理 JWK 的功能,这对于加密、解密和签名过程至关重要。

请查看我们的文档,了解更多关于 JWS 签名 的信息。

let keyJWK = JWK(keyType: .rsa, algorithm: "A256GCM", keyID: rsaKeyId, e: rsaKeyExponent, n: rsaKeyModulus)
// ---------------------
let key = secp256k1.Signing.PrivateKey()
let keyJWK = key.jwkRepresentation
// ---------------------
let key = Curve25519.KeyAgreement.PrivateKey()
let publicKeyJWK = key.jwkRepresentation.publicKey

JWS (JSON Web Signature)

JWS 是一种用于对任意内容进行数字签名的标准,如 RFC 7515 中所详述。 此模块支持创建和验证数字签名,确保签名数据的完整性和真实性。

#### 支持的算法

Bouncy castle secp256k1 故障保护

Bouncy Castle(一个著名的密码学 Java 库,与 Nimbus JWT 和 bitcoin secp256k1 一起使用)给出的签名之间存在差异。 签名采用 DER 格式,并且由于某种原因,R 和 S 被颠倒了。

要使签名能够被 Bouncy Castle 验证,您可以设置此标志 ES256KSigner.outputFormat = .der,它会将签名转换为 DER 格式。

考虑到这一点,该库提供了一种启用 Nimbus/Bouncy Castle 签名验证的功能,可以通过设置标志 ES256KVerifier.bouncyCastleFailSafe = true 来启用。 此过程需要操纵内部签名,并反转 R 和 S 字节,请您自行承担风险使用它,因为它可能会增加安全漏洞。

示例

let payload = "Hello world".data(using: .utf8)!
let key = secp256k1.Signing.PrivateKey()

let jws = try JWS(payload: payload, key: key)

let jwsString = jws.compactSerialization

try JWS(jwsString: jwsString).verify(key: key)

如果您想在默认标头之外向 JWS 添加其他标头

let rsaKeyId = "Hello-keyId"
var header = DefaultJWSHeaderImpl()
header.keyID = rsaKeyId
header.algorithm = .rsa512

let keyJWK = JWK(keyType: .rsa, algorithm: "RSA512", keyID: rsaKeyId, e: rsaKeyExponent, n: rsaKeyModulus)
let jwe = try JWS(payload: payload, protectedHeader: header, key: jwk)

带有未编码 payload 的 JWS(仅限紧凑字符串)

JWS 还支持未编码的 payload,这在 payload 已经以紧凑、URL 安全的形式存在的情况下非常有用(例如,在小型 JSON 对象或 base64url 编码字符串的情况下)。 这有助于减小 JWS 的整体大小,并通过避免冗余编码步骤来提高性能。

要创建带有未编码 payload 的 JWS,您需要将 b64 标头参数设置为 false,并确保 payload 采用兼容的格式。

示例

let payload = "Hello world".data(using: .utf8)!
let key = secp256k1.Signing.PrivateKey()

let jws = try JWS(payload: payload, key: key, options: [.unencodedPayload])

let jwsString = jws.compactSerialization

try JWS.verify(jwsString: jwsString, payload: payload, key: key)

JWE (JSON Web Encryption)

JWE 使用基于 JSON 的数据结构表示加密内容,遵循 RFC 7516 的指导方针。 此模块包括用于加密和解密数据、管理加密密钥以及处理各种加密算法和方法的功能。

请查看我们的文档,了解更多关于 JWE 加密 的信息。

支持的算法

  1. 密钥管理算法:

    • RSA1_5 (RSAES-PKCS1-v1_5)
    • RSA-OAEP (使用默认参数的 RSAES OAEP)
    • RSA-OAEP-256 (使用 SHA-256 和 MGF1 with SHA-256 的 RSAES OAEP)
    • A128KW (使用默认 128 位密钥的 AES 密钥包装)
    • A192KW (使用 192 位密钥的 AES 密钥包装)
    • A256KW (使用 256 位密钥的 AES 密钥包装)
    • dir (直接使用共享对称密钥)
    • ECDH-ES (椭圆曲线 Diffie-Hellman 临时静态密钥协商)
    • ECDH-ES+A128KW (ECDH-ES 使用 Concat KDF 和 A128KW 包装)
    • ECDH-ES+A192KW (ECDH-ES 使用 Concat KDF 和 A192KW 包装)
    • ECDH-ES+A256KW (ECDH-ES 使用 Concat KDF 和 A256KW 包装)
    • ECDH-1PU (椭圆曲线 Diffie-Hellman 单程统一模型)
    • ECDH-1PU+A128KW (ECDH-1PU 使用 Concat KDF 和 A128KW 包装)
    • ECDH-1PU+A192KW (ECDH-1PU 使用 Concat KDF 和 A192KW 包装)
    • ECDH-1PU+A256KW (ECDH-1PU 使用 Concat KDF 和 A256KW 包装)
    • A128GCMKW (使用 128 位密钥的 AES GCM 密钥包装)
    • A192GCMKW (使用 192 位密钥的 AES GCM 密钥包装)
    • A256GCMKW (使用 256 位密钥的 AES GCM 密钥包装)
    • PBES2-HS256+A128KW (带有 HMAC SHA-256 和 "A128KW" 包装的 PBES2)
    • PBES2-HS384+A192KW (带有 HMAC SHA-384 和 "A192KW" 包装的 PBES2)
    • PBES2-HS512+A256KW (带有 HMAC SHA-512 和 "A256KW" 包装的 PBES2)
    • 注意:ECDH-1PU 在 draft-ietf-jose-cfrg-curves-10 中指定
  2. 内容加密算法:

    • A128CBC-HS256 (使用 128 位密钥和 HMAC SHA-256 的 AES CBC)
    • A192CBC-HS384 (使用 192 位密钥和 HMAC SHA-384 的 AES CBC)
    • A256CBC-HS512 (使用 256 位密钥和 HMAC SHA-512 的 AES CBC)
    • A128GCM (使用 128 位密钥的 AES GCM)
    • A192GCM (使用 192 位密钥的 AES GCM)
    • A256GCM (使用 256 位密钥的 AES GCM)
    • C20P (ChaCha20-Poly1305)
    • XC20P (XChaCha20-Poly1305)
    • 注意:ChaChaPoly20-Poly1305 和 XChaChaPoly20-Poly1305 在 draft-amringer-jose-chacha-02 中指定
  3. 压缩算法:

    • DEFLATE (zip)

示例1

let payload = "Hello world".data(using: .utf8)!
let keyJWK = JWK(keyType: .rsa, algorithm: "A256GCM", keyID: rsaKeyId, e: rsaKeyExponent, n: rsaKeyModulus)


let serialization = try JWE(
    payload: payload,
    keyManagementAlg: .a256KW,
    encryptionAlgorithm: .a256GCM,
    compressionAlgorithm: .deflate,
    recipientKey: keyJWK
)

let compact = serialization.compactSerialization

let jwe = try JWE(compactString: compact)
let decrypted = try jwe.decrypt(recipientKey: recipientKey)

示例2

let payload = "Hello world".data(using: .utf8)!
let key = P256.Signing.PrivateKey()


let serialization = try JWE(
    payload: payload,
    keyManagementAlg: .a256KW,
    encryptionAlgorithm: .a256GCM,
    compressionAlgorithm: .deflate,
    recipientKey: key
)

let compact = serialization.compactSerialization()

let jwe = try JWE(compactString: compact)
let decrypted = try jwe.decrypt(recipientKey: recipientJWK)

如果您想在默认标头之外向 JWE 添加其他标头

let rsaKeyId = "Hello-keyId"
var header = DefaultJWEHeaderImpl()
header.keyID = rsaKeyId
header.keyManagementAlgorithm = .rsaOAEP256
header.encodingAlgorithm = .a256GCM
let keyJWK = JWK(keyType: .rsa, algorithm: "A256GCM", keyID: rsaKeyId, e: rsaKeyExponent, n: rsaKeyModulus)
let jwe = try JWE(payload: wrappedPayload, protectedHeader: header, recipientKey: jwk)

JWT (JSON Web Token)

JWT 是一种紧凑的、URL 安全的方式,用于表示要在两方之间传递的声明。 此模块提供用于创建、解析、验证和操作 JWT 的工具,并支持各种签名和加密方法,如 RFC 7519 中所规定。

请查看我们的文档,了解更多关于 JWT 令牌 的信息。

特点

  1. 已签名的 JWT:

    • 支持数字签名以验证令牌的真实性和完整性。
    • 利用 JWS(JSON Web 签名)标准。
    • 支持之前提到的所有 JWS 算法。
  2. 已加密的 JWT:

    • 方便对令牌内容进行加密以确保机密性。
    • 使用 JWE(JSON Web 加密)实现强大的加密标准。
    • 支持之前提到的所有 JWE 算法。
  3. 嵌套 JWT (JWS + JWE):

    • 实现嵌套 JWT,其中 JWT 先被签名,然后被加密,从而提供 JWS 和 JWE 的双重优势。
    • 确保令牌首先经过身份验证 (JWS),然后受到保护以确保隐私 (JWE)。
  4. 用于声明创建的特定领域语言 (DSL):

    • 允许使用特定领域语言 (DSL) 以更具声明性的方法创建声明。
    • 方便以可读且结构化的方式创建标准和自定义声明。
  5. 声明验证:

    • 提供验证 JWT 声明的广泛功能。
    • 包括标准声明,如颁发者 (iss)、主题 (sub)、受众 (aud)、过期时间 (exp)、生效时间 (nbf) 和颁发时间 (iat)。
    • 自定义声明验证以满足特定的安全要求。

示例

let key = P256.Signing.PrivateKey()
let mockClaims = DefaultJWTClaims(
    iss: "testAlice",
    sub: "Alice",
    exp: expiredAt
)

let jwt = try JWT.signed(
    payload: mockClaims,
    protectedHeader: DefaultJWSHeaderImpl(algorithm: .ES256),
    key: key
)

let jwtString = jwt.jwtString

let verifiedJWT = try JWT<DefaultJWTClaims>.verify(jwtString: jwtString, senderKey: key)
let verifiedPayload = verifiedJWT.payload
let key = Curve25519.KeyAgreement.PrivateKey()
let mockClaims = DefaultJWTClaims(
    iss: "testAlice",
    sub: "Alice",
    exp: expiredAt
)

let jwt = try JWT.encrypt(
    payload: payload,
    protectedHeader: DefaultJWSHeaderImpl(keyManagementAlgorithm: .a128KW, encodingAlgorithm: .a128CBCHS256),
    recipientKey: key
)

let jwtString = jwt.jwtString

let verifiedJWT = try JWT<DefaultJWTClaims>.verify(jwtString: jwtString, recipientKey: key)
let verifiedPayload = verifiedJWT.payload

JWA (JSON Web Algorithms)

JWA 指定在 Jose 上下文中使用密码算法来执行数字签名和内容加密,如 RFC 7518 中所详述。 它包括各种类型算法的标准,例如 RSA、AES、HMAC 等。

贡献

欢迎对该库做出贡献。 请确保您的贡献符合 Jose 标准,并为现有功能增加价值。

参考

致谢

特别感谢 swift-jose 仓库 (由 Zsombor Szabo 开发),它为本项目提供了灵感。我采用了其中的部分 JWK 实现以及一些测试向量,这些对完善本库的某些方面起到了至关重要的作用。衷心感谢他们对开源社区的贡献。

许可证

本项目基于 Apache License 2.0 协议授权。详情请查看 LICENSE 文件。