JOSESwift is a modular and extensible framework for the JOSE standards JWS, JWE, and JWK written in Swift. It is designed for usage on iOS but could be extended to be used in pure Swift environments.
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.
- 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.
🔏 JWS | 🔐 JWE | 🔑 JWK | |||||||
---|---|---|---|---|---|---|---|---|---|
Digital Signatures and MACs | Key Management | Content Encryption | Keys | ||||||
HS256 | RSA1_5 | ✅ | A128CBC-HS256 | RSA | ✅ | ||||
HS384 | RSA-OAEP | ✅ | A128CBC-HS384 | EC | ✅ | ||||
HS512 | RSA-OAEP-256 | ✅ | A128CBC-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 supports the DEFLATE compression algorithm for JWE.
DEF |
---|
✅ |
For interchangeability JOSESwift currently supports compact serialization for JWS and for JWE.
Compact Serialization | JSON Serialization |
---|---|
✅ |
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.
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.
JOSESwift covers three functional aspects:
A JWS
encapsulates and secures data using a digital signature which can be verified by the receiver of the JWS
.
In order to construct a JWS we need to provide the following parts:
- Header
- Payload
- Signer
let header = JWSHeader(algorithm: .RS512)
Optionally you can set addtitional parameters:
header.kid = "2018-10-08"
header.typ = "JWS"
let message = "Summer ⛱, Sun ☀️, Cactus 🌵".data(using: .utf8)!
let payload = Payload(message)
The signer algorithm must match the header algorithm.
let privateKey: SecKey = /* ... */
let signer = Signer(signingAlgorithm: .RS512, privateKey: privateKey)!
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.
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.
A JWE encapsulates and secures data by encrypting it. It can be decrypted by the receiver of the JWE.
In order to construct a JWE we need to provide the following parts:
- Header
- Payload
- Encrypter
let header = JWEHeader(algorithm: .RSA1_5, encryptionAlgorithm: .A256CBCHS512)
Optionally you can set addtitional parameters:
header.kid = "2018-10-08"
header.typ = "JWE"
let message = "Summer ⛱, Sun ☀️, Cactus 🌵".data(using: .utf8)!
let payload = Payload(message)
The encrypter algorithms must match the header algorithms.
let publicKey: SecKey = /* ... */
let encrypter = Encrypter(keyEncryptionAlgorithm: .RSA1_5, encryptionKey: publicKey, contentEncyptionAlgorithm: .A256CBCHS512)!
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.
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.
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.
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.
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.
"key_ops"
and "x5c"
when decoding. This is due to a bug in our decoding implementation. See #117 for details.
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.
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.
You can find detailed information about the relevant JOSE standards in the respective RFCs:
- RFC-7515: JSON Web Signature (JWS)
- RFC-7516: JSON Web Encryption (JWE)
- RFC-7517: JSON Web Key (JWK)
- RFC-7518: JSON Web Algorithms (JWA)
Don’t forget to check our our wiki for more detailed documentation.
Feel free to contact the project maintainers at joseswift@airsidemobile.com.
JOSESwift is maintained by Airside Mobile.
@carol-mohemian, @daniel-mohemian, @gigi-mohemian
The logo was designed by Ivan Leuzzi.
To the following projects, which served us as reference and inspiration during development:
JOSESwift is licensed under the Apache License 2.0. See LICENSE for details.