Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/airsidemobile/JOSESwift

A framework for the JOSE standards JWS, JWE, and JWK written in Swift.
https://github.com/airsidemobile/JOSESwift

encryption ios jose jwe jwk jws signing swift

Last synced: about 2 months ago
JSON representation

A framework for the JOSE standards JWS, JWE, and JWK written in Swift.

Awesome Lists containing this project

README

        

![JOSESwift](logo/JOSESwift-full.svg)


**JOSESwift** is a modular and extensible framework for the [JOSE](https://datatracker.ietf.org/wg/jose/about/) standards [**JWS**](https://tools.ietf.org/html/rfc7515), [**JWE**](https://tools.ietf.org/html/rfc7516), and [**JWK**](https://tools.ietf.org/html/rfc7517) written in Swift.

[![CircleCI](https://circleci.com/gh/airsidemobile/JOSESwift/tree/master.svg?style=svg)](https://circleci.com/gh/airsidemobile/JOSESwift/tree/master)

> :bulb: Please note that this implementation of the JOSE standards is not fully complete yet. For example, there is only a limited set of supported algorithms available at the moment. Moreover we currently only support compact serialization of JOSE types. If you are missing a specific feature, algorithm, or serialization, feel free to [submit a pull request](#contributing).

## Contents

- [Features](#features)
- [Installation](#installation)
- [CocoaPods](#cocoapods)
- [Carthage](#carthage)
- [Swift Package Manager](#swift-package-manager)
- [Usage](#usage)
- [JWS: Digital Signatures](#jws-digital-signatures)
- [JWE: Encryption and Decryption](#jwe-encryption-and-decryption)
- [JWK: Representing Keys](#jwk-representing-keys)
- [Security](#security)
- [Contributing](#contributing)
- [Resources](#resources)
- [Contact](#contact)
- [Credits](#credits)
- [License](#license)

## Features

- **JWS**: Digitally signing and verifying arbitrary data using the JWS standard.
- **JWE**: Encrypting and decrypting arbitrary data using the JWE standard.
- **JWK**: Encoding and decoding cryptographic keys.

If you are missing a specific feature, algorithm, or serialization, feel free to [submit a pull request](#contributing).

### Cryptographic Algorithms


:lock_with_ink_pen: JWS

:closed_lock_with_key: JWE

:key: JWK


Digital Signatures and MACs
Key Management
Content Encryption
Keys

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:white_check_mark: 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:white_check_mark:
RS384:white_check_mark: A192KW:white_check_mark: A192GCM:white_check_mark:
RS512:white_check_mark: A256KW:white_check_mark: A256GCM:white_check_mark:
ES256:white_check_mark: dir:white_check_mark:
ES384:white_check_mark: ECDH-ES:white_check_mark:
ES512:white_check_mark: ECDH-ES+A128KW:white_check_mark:
PS256:white_check_mark: ECDH-ES+A192KW:white_check_mark:
PS384:white_check_mark: ECDH-ES+A256KW:white_check_mark:
PS512:white_check_mark: A128GCMKW
A192GCMKW
A256GCMKW
PBES2-HS256+A128KW:white_check_mark:
PBES2-HS384+A192KW:white_check_mark:
PBES2-HS512+A256KW:white_check_mark:

### Serializations

For interchangeability JOSESwift currently supports compact serialization [for JWS](https://tools.ietf.org/html/rfc7515#section-3.1) and [for JWE](https://tools.ietf.org/html/rfc7516#section-3.1).

| Compact Serialization | JSON Serialization |
| :-------------------: | :----------------: |
| :white_check_mark: | |

### Compression Algorithms

JOSESwift supports the [DEFLATE](https://tools.ietf.org/html/rfc1951) compression algorithm [for JWE](https://tools.ietf.org/html/rfc7516#section-4.1.3).

## 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`:

``` ruby
source 'https://cdn.cocoapods.org/'
platform :ios, '13.0'
use_frameworks!

target '' do
pod 'JOSESwift', '~> 3.0'
end
```

Then install it by running `pod install`. More documentation on using CocoaPods can be found [here](https://cocoapods.org).

### Carthage

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

```
github "airsidemobile/JOSESwift" ~> 3.0
```

Then build it by running `carthage update` and drag the built framework into your Xcode project. More documentation on using Carthage can be found [here](https://github.com/Carthage/Carthage).

### 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](https://developer.apple.com/documentation/xcode/adding_package_dependencies_to_your_app).

Alternatively, when using Swift Package Manager manually include the following dependency in your `Package.swift` file. See [Apple's documentation](https://developer.apple.com/documentation/swift_packages/package/dependency) for more details on specifying dependency version requirements.

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

## Usage

JOSESwift covers three functional aspects:

1. [JWS: Digital Signatures](#jws-digital-signatures)
- [Signing data](#signing-data)
- [Verifying data](#verifying-data)
2. [JWE: Encryption and Decryption](#jwe-encryption-and-decryption)
- [Encrypting data](#encrypting-data)
- [Decrypting data](#decrypting-data)
3. [JWK: Representing Keys](#jwk-representing-keys)
- [Encoding RSA Public Keys](#encoding-rsa-public-keys)
- [Decoding RSA Public Keys](#decoding-rsa-public-keys)

****

### JWS: Digital Signatures

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

#### Signing Data

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

1. Header
2. Payload
3. Signer

##### Header

``` swift
var header = JWSHeader(algorithm: .RS512)
```

You can set [registered header parameters](https://tools.ietf.org/html/rfc7515#section-4.1) via convenient accessors:

``` swift
header.kid = "2018-10-08"

header.typ = "JWS"
```

[Public](https://tools.ietf.org/html/rfc7515#section-4.2) and [private](https://tools.ietf.org/html/rfc7515#section-4.3) header parameters can be set and read like so:

``` swift
try header.set("rice", forParameter: "meal")
let meal = header.get(parameter: "meal") // "rice"
header.remove(parameter: "meal")
```

##### Payload

``` swift
let message = "Summer β›±, Sun β˜€οΈ, Cactus 🌡".data(using: .utf8)!

let payload = Payload(message)
```

##### Signer

The signer algorithm must match the header algorithm.

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

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

##### 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.

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

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

More details about constructing a JWS can be found [in the wiki](../../wiki/jws).

#### Verifying Data

``` swift
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 🌡
}
```

More details about verifying an existing, serialized JWS can be found [in the wiki](../../wiki/jws).

****

### 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

##### Header

``` swift
var header = JWEHeader(keyManagementAlgorithm: .RSA1_5, contentEncryptionAlgorithm: .A256CBCHS512)
```

You can set [registered header parameters](https://tools.ietf.org/html/rfc7516#section-4.1):

``` swift
header.kid = "2018-10-08"

header.typ = "JWE"
```

[Public](https://tools.ietf.org/html/rfc7515#section-4.2) and [private](https://tools.ietf.org/html/rfc7515#section-4.3) header parameters can be set and read like so:

``` swift
try header.set("rice", forParameter: "meal")
let meal = header.get(parameter: "meal") // "rice"
header.remove(parameter: "meal")
```

##### Payload

``` swift
let message = "Summer β›±, Sun β˜€οΈ, Cactus 🌡".data(using: .utf8)!

let payload = Payload(message)
```

##### Encrypter

The encrypter algorithms must match the header algorithms.

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

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

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.

``` swift
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
```

More details about constructing a JWE can be found [in the wiki](../../wiki/jwe).

#### Decrypting Data

``` swift
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 🌡
}
```

More details about decrypting an existing, serialized JWE can be found [in the wiki](../../wiki/jwe).

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

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

let jwk = try! RSAPublicKey(publicKey: publicKey)

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

More details about encoding RSA public keys can be found [in the wiki](../../wiki/jwk).

#### Decoding RSA Public Keys

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

let jwk = try! RSAPublicKey(data: json)

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

More details about decoding RSA public keys can be found [in the wiki](../../wiki/jwk).

:warning: We currently ignore the key parameters [`"key_ops"`](https://tools.ietf.org/html/rfc7517#section-4.3) and [`"x5c"`](https://tools.ietf.org/html/rfc7517#section-4.7) when decoding. This is due to a bug in our decoding implementation. See [#117](https://github.com/airsidemobile/JOSESwift/issues/117) for details.

## Security

JOSESwift uses [Apple's Security framework](https://developer.apple.com/documentation/security), [Apple’s CommonCrypto](https://opensource.apple.com//source/CommonCrypto/), and [Apples's CryptoKit](https://developer.apple.com/documentation/cryptokit/) for cryptography.

For security disclosures or related matters, please contact .

See our [security policy](SECURITY.md) 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](.github/CONTRIBUTING.md) for more information.

## Resources

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

- [RFC-7515:](https://tools.ietf.org/html/rfc7515) JSON Web Signature (JWS)
- [RFC-7516:](https://tools.ietf.org/html/rfc7516) JSON Web Encryption (JWE)
- [RFC-7517:](https://tools.ietf.org/html/rfc7517) JSON Web Key (JWK)
- [RFC-7518:](https://tools.ietf.org/html/rfc7518) JSON Web Algorithms (JWA)

Don’t forget to check our [our wiki](https://github.com/mohemian/jose-ios/wiki) for more detailed documentation.

## Contact

Feel free to contact the project maintainers at .

## Credits

JOSESwift is maintained by [Airside Mobile](https://www.airsidemobile.com).

### Project Maintainers

[@daniel-moh](https://github.com/daniel-moh),
[@haeser](https://github.com/haeser)

### Logo

The logo was designed by Ivan Leuzzi.

### Thanks

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

- [Heimdall](https://github.com/henrinormak/Heimdall)
- [Nimbus JOSE + JWT](https://connect2id.com/products/nimbus-jose-jwt)

## License

JOSESwift is licensed under the Apache License 2.0. See [LICENSE](LICENSE) for details.