用 Swift 编写的 JOSE 标准 JWS、JWE 和 JWK 的框架

JOSESwift 是用 Swift 编写的 JOSE 标准 JWS、JWEJWK 的模块化和可扩展框架。

圈子CI

:灯泡:请注意,JOSE 标准的实施尚未完全完成。例如,目前只有一组有限的受支持算法可用。此外,我们目前仅支持JOSE类型的紧凑序列化。如果缺少特定功能、算法或序列化,请随时提交拉取请求

特征

  • JWS:使用 JWS 标准对任意数据进行数字签名和验证。
  • JWE:使用 JWE 标准加密和解密任意数据。
  • JWK:编码和解码加密密钥。

如果缺少特定功能、算法或序列化,请随时提交拉取请求

加密算法

:lock_with_ink_pen: JWS :closed_lock_with_key: JWE :键: JWK
数字签名和 MAC 密钥管理 内容加密 钥匙
HS256:white_check_mark: RSA1_5:white_check_mark: A128CBC-HS256:white_check_mark: RSA:white_check_mark:
HS384:white_check_mark: RSA-OAEP:white_check_mark: A192CBC-HS384 EC:white_check_mark:
HS512:white_check_mark: RSA-OAEP-256:white_check_mark: A256CBC-HS512:white_check_mark: oct:white_check_mark:
RS256:white_check_mark: A128KW:white_check_mark: A128GCM
RS384:white_check_mark: A192KW:white_check_mark: A192GCM
RS512:white_check_mark: A256KW:white_check_mark: A256GCM
ES256:white_check_mark: dir:white_check_mark:
ES384:white_check_mark: ECDH-ES
ES512:white_check_mark: ECDH-ES+A128KW
PS256:white_check_mark: ECDH-ES+A192KW
PS384:white_check_mark: ECDH-ES+A256KW
PS512:white_check_mark: A128GCMKW
A192GCMKW
A256GCMKW
PBES2-HS256+A128KW
PBES2-HS384+A192KW
PBES2-HS512+A256KW

Serializations

For interchangeability JOSESwift currently supports compact serialization for JWS and for JWE.

Compact Serialization JSON Serialization
:white_check_mark:

Compression Algorithms

JOSESwift supports the DEFLATE compression algorithm for JWE.

Installation

JOSESwift integrates nicely into your iOS and macOS projects. We support the following package managers:

CocoaPods

To integrate JOSESwift into your Xcode project, include it in your :Podfile

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

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

Then install it by running . More documentation on using CocoaPods can be found here.pod install

Carthage

To integrate JOSESwift in your Xcode project, include it in your :Cartfile

github "airsidemobile/JOSESwift" ~> 2.3

Then build it by running and drag the built framework into your Xcode project. More documentation on using Carthage can be found here.carthage update

Swift Package Manager

To integrate JOSESwift in your Xcode project as a Swift package, follow Apple's article on how to add package dependencies to your app.

Alternatively, when using Swift Package Manager manually include the following dependency in your file. See Apple's documentation for more details on specifying dependency version requirements.Package.swift

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

Usage

JOSESwift covers three functional aspects:

  1. JWS: Digital Signatures
  2. JWE: Encryption and Decryption
  3. JWK: Representing Keys

JWS: Digital Signatures

A encapsulates and secures data using a digital signature which can be verified by the receiver of the .JWSJWS

Signing Data

In order to construct a JWS we need to provide the following parts:

  1. Header
  2. Payload
  3. Signer
let header = JWSHeader(algorithm: .RS512)
Swift

Optionally you can set addtitional parameters:

header.kid = "2018-10-08"

header.typ = "JWS"
Swift
Payload
let message = "Summer ⛱, Sun ☀️, Cactus ?".data(using: .utf8)!

let payload = Payload(message)
Swift
Signer

The signer algorithm must match the header algorithm.

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

let signer = Signer(signingAlgorithm: .RS512, privateKey: privateKey)!
Swift
Serializing

The JWS compact serialization is a URL-safe string that can easily be transmitted to a third party using a method of your choice.

guard let jws = try? JWS(header: header, payload: payload, signer: signer) else { ... }

print(jws.compactSerializedString) // ey (...) J9.U3 (...) LU.na (...) 1A
Swift

More details about constructing a JWS can be found in the wiki.

Verifying Data

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

let serialization = "ey (..) n0.HK (..) pQ.yS (..) PA.AK (..) Jx.hB (..) 7w"
Swift
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 ?
}
Swift

More details about verifying an existing, serialized JWS can be found in the wiki.


JWE: Encryption and Decryption

A JWE encapsulates and secures data by encrypting it. It can be decrypted by the receiver of the JWE.

Encrypting Data

In order to construct a JWE we need to provide the following parts:

  1. Header
  2. Payload
  3. Encrypter
let header = JWEHeader(keyManagementAlgorithm: .RSA1_5, contentEncryptionAlgorithm: .A256CBCHS512)
Swift

Optionally you can set addtitional parameters:

header.kid = "2018-10-08"

header.typ = "JWE"
Swift
Payload
let message = "Summer ⛱, Sun ☀️, Cactus ?".data(using: .utf8)!

let payload = Payload(message)
Swift
Encrypter

The encrypter algorithms must match the header algorithms.

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

let encrypter = Encrypter(keyManagementAlgorithm: .RSA1_5, contentEncryptionAlgorithm: .A256CBCHS512, encryptionKey: publicKey)!
Swift

Note that the type of the provided encryption key must match the specified key management algorithm as shown in the following table.

Key Management Algorithm Encryption Key Type
RSA1_5 SecKey
RSAOAEP SecKey
RSAOAEP256 SecKey
A128KW Data
A192KW Data
A256KW Data
direct Data
Serialization

The JWE compact serialization is a URL-safe string that can easily be transmitted to a third party using a method of your choice.

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
Swift

More details about constructing a JWE can be found in the wiki.

Decrypting Data

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

let serialization = "ey (..) n0.HK (..) pQ.yS (..) PA.AK (..) Jx.hB (..) 7w"
Swift
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 ?
}
Swift

More details about decrypting an existing, serialized JWE can be found in the wiki.

Note that the type of the provided decryption key must match the specified key management algorithm as shown in the following table.

Key Management Algorithm Decryption Key Type
RSA1_5 SecKey
RSAOAEP SecKey
RSAOAEP256 SecKey
A128KW Data
A192KW Data
A256KW Data
direct Data

JWK: Representing Keys

A JWK is a JSON data structure that represents a cryptographic key. You could use it, for instance, as the payload of a JWS or a JWE to transmit your public key to a server.

Encoding RSA Public Keys

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

let jwk = try! RSAPublicKey(publicKey: publicKey)

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

More details about encoding RSA public keys can be found in the wiki.

Decoding RSA Public Keys

let json: Data = /* ... */

let jwk = try! RSAPublicKey(data: json)

let publicKey: SecKey = try! jwk.converted(to: SecKey.self)
Swift

More details about decoding RSA public keys can be found in the wiki.

:warning: We currently ignore the key parameters "key_ops" and "x5c" when decoding. This is due to a bug in our decoding implementation. See #117 for details.

Security

JOSESwift uses Apple's Security framework and Apple’s CommonCrypto for cryptography.

For security disclosures or related matters, please contact joseswift@airsidemobile.com.

See our security policy for more information.

Contributing

Contributions to the project are encouraged and more than welcome. :nerd_face:

If you want to contribute, please submit a pull request.
For feature requests, discussions, or bug reports, just open an issue.

See our contributing guidelines for more information.

Resources

You can find detailed information about the relevant JOSE standards in the respective RFCs:

Don’t forget to check our our wiki for more detailed documentation.

Contact

Feel free to contact the project maintainers at joseswift@airsidemobile.com.

Credits

JOSESwift is maintained by Airside Mobile.

Project Authors and Maintainers

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

Reviewers

@haeser, @michael-mohemian

The logo was designed by Ivan Leuzzi.

Thanks

To the following projects, which served us as reference and inspiration during development:

License

JOSESwift is licensed under the Apache License 2.0. See LICENSE for details.

GitHub

https://github.com/airsidemobile/JOSESwift