Skip to content

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

License

Notifications You must be signed in to change notification settings

CleverPumpkin/JOSESwift

 
 

Repository files navigation

JOSESwift


JOSESwift is a modular and extensible framework for the JOSE standards JWS, JWE, and JWK written in Swift. It is designed with usage on iOS and pure Swift environments in mind.

Build Status

As of now, usage is limited to iOS. See Security for details.

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

Contents

Features

If you are missing a specific feature, algorithm, or serialization, feel free to submit a pull request.

General

Supported serializations:

Compact Serialization JSON Serialization

JWS 📝

Digitally signing and verifying arbitrary data using the JWS standard.

Supported algorithms:

HS256 HS384 HS512 RS256 RS384 RS512 ES256 ES384 ES512 PS256 PS384 PS512

JWE 🔒

Encrypting and decrypting arbitrary data using the JWE standard.

Supported key encryption algorithms:

RSA1_5 RSA-OAEP RSA-OAEP-256 A128KW A192KW A256KW dir ECDH-ES ECDH-ES+A128KW ECDH-ES+A192KW ECDH-ES+A256KW A128GCMKW A192GCMKW A256GCMKW PBES2-HS256+A128KW PBES2-HS384+A192KW PBES2-HS512+A256KW

Supported content encryption algorithms:

A128CBC-HS256 A192CBC-HS384 A256CBC-HS512 A128GCM A192GCM A256GCM

JWK 🔑

Encoding and decoding RSA public key data in PKCS#1 format as well as iOS SecKeys.

Supported key types:

EC RSA oct

Installation

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'
end

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

Carthage

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

github "airsidemobile/JOSESwift"

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.

Usage

JOSESwift covers three functional aspects:

  1. JWS: Digital Signatures
  2. JWE: Encryption and Decryption
  3. JWK: Representing 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
let header = JWSHeader(algorithm: .RS512)

Optionally you can set addtitional parameters:

header.kid = "2018-10-08"

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

let payload = Payload(message)
Signer

The signer algorithm must match the header algorithm.

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.

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.

Verifying Data

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 🌵
}

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
Header
let header = JWEHeader(algorithm: .RSA1_5, encryptionAlgorithm: .A256CBCHS512)

Optionally you can set addtitional parameters:

header.kid = "2018-10-08"

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

let payload = Payload(message)
Encrypter

The encrypter algorithms must match the header algorithms.

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

let encrypter = Encrypter(keyEncryptionAlgorithm: .RSA1_5, encryptionKey: publicKey, contentEncyptionAlgorithm: .A256CBCHS512)!
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

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"
do {
    let jwe = try JWE(compactSerialization: serialization)
    let decrypter = Decrypter(keyDecryptionAlgorithm: .RSA1_5, decryptionKey: privateKey, contentDecryptionAlgorithm: .A256CBCHS512)!
    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.


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"}

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)

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

⚠️ 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 the iOS Security framework and Apple’s CommonCrypto for cryptography.

It is designed in a way that it is easy to switch out the implementation for a specific cryptographic operation. Non-iOS users can add their own platform independent crypto implementation instead of the ones mentioned above.

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

Contributing

Contributions to the project are encouraged and more than welcome. 🤓

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

Logo

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.

About

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

Resources

License

Code of conduct

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Swift 93.4%
  • Shell 3.6%
  • Ruby 2.7%
  • Objective-C 0.3%