Skip to content

Commit

Permalink
docs: Update docs and examples also created tests for every example s…
Browse files Browse the repository at this point in the history
…o in the future they match
  • Loading branch information
beatt83 committed Dec 7, 2024
1 parent 1d48cab commit a263b8e
Show file tree
Hide file tree
Showing 12 changed files with 918 additions and 158 deletions.
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ let jws = try JWS(payload: payload, key: key, options: [.unencodedPayload])
let jwsString = jws.compactSerialization
try JWS.verify(jwsString: jwsString, payload: payload.data(using: .utf8)!, key: key)
try JWS.verify(jwsString: jwsString, payload: payload, key: key)
```


Expand Down Expand Up @@ -382,14 +382,14 @@ let serialization = try JWE(
payload: payload,
keyManagementAlg: .a256KW,
encryptionAlgorithm: .a256GCM,
compressionAlgorithm: .zip,
compressionAlgorithm: .deflate,
recipientKey: keyJWK
)

let compact = serialization.compactSerialization()
let compact = serialization.compactSerialization

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

Example2:
Expand All @@ -403,7 +403,7 @@ let serialization = try JWE(
payload: payload,
keyManagementAlg: .a256KW,
encryptionAlgorithm: .a256GCM,
compressionAlgorithm: .zip,
compressionAlgorithm: .deflate,
recipientKey: key
)

Expand Down
32 changes: 18 additions & 14 deletions Sources/jose-swift/jose-swift.docc/Articles/JWEEncryption.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@ Example:

```
{
alg”: “RSA-OAEP,
enc”: “A256GCM
"alg": "RSA-OAEP",
"enc": "A256GCM"
}
```

Expand All @@ -94,8 +94,8 @@ The authentication tag is used to ensure the integrity and authenticity of the c
Using the **jose-swift** library, creating a JWE is straightforward. Here’s an example of how to create a JWE:

```swift
let payload = Hello, World!.data(using: .utf8)!
let recipientKey = try RSA(publicKey: Data(base64Encoded: “your-public-key”)!)
let payload = "Hello, World!".data(using: .utf8)!
let recipientKey = try RSA(rawRepresentation: Data(base64Encoded: “your-public-key”)!)

let jwe = try JWE(
payload: payload,
Expand All @@ -104,8 +104,9 @@ let jwe = try JWE(
recipientKey: recipientKey
)

print(JWE: (jwe.compactSerialization))
print("JWE: \(jwe.compactSerialization)")
```
Example 3.1

In this example, the `JWE` initializer encrypts the payload using the RSA-OAEP key management algorithm and the A256GCM content encryption algorithm.

Expand All @@ -119,8 +120,9 @@ let recipientKey = try RSA(privateKey: Data(base64Encoded: “your-private-key
let jwe = try JWE(compactString: jweString)

let decryptedPayload = try jwe.decrypt(recipientKey: recipientKey)
print(Decrypted payload: (String(data: decryptedPayload, encoding: .utf8)!))
print("Decrypted payload: \(String(data: decryptedPayload, encoding: .utf8)!)")
```
Example 3.2

In this example, the `decrypt` method decrypts the JWE using the private key.

Expand All @@ -129,20 +131,21 @@ In this example, the `decrypt` method decrypts the JWE using the private key.
You can include custom headers in your JWE to add additional metadata. Here’s an example:

```swift
let payload = Hello, World!.data(using: .utf8)!
let payload = "Hello, World!".data(using: .utf8)!
let recipientKey = try RSA(publicKey: Data(base64Encoded: “your-public-key”)!)

var header = DefaultJWEHeaderImpl(keyManagementAlgorithm: .a256GCMKW, encodingAlgorithm: .a256GCM)
header.keyID = key-id
var header = DefaultJWEHeaderImpl(keyManagementAlgorithm: .rsaOAEP256, encodingAlgorithm: .a256GCM)
header.keyID = "key-id"

let jwe = try JWE(
payload: payload,
protectedHeader: header,
recipientKey: recipientKey
)

print(JWE: (jwe.compactSerialization))
print("JWE: \(jwe.compactSerialization)")
```
Example 3.3

In this example, the `kid` (key ID) field is added to the header to specify which key was used for encryption.

Expand All @@ -151,8 +154,8 @@ In this example, the `kid` (key ID) field is added to the header to specify whic
A Nested JWE is a JWE that is encrypted and then encrypted again. This provides an additional layer of security by ensuring both the confidentiality and authenticity of the message. Here’s how to create a nested JWE:

```swift
let nestedPayload = Nested payload.data(using: .utf8)!
let nestedRecipientKey = try RSA(publicKey: Data(base64Encoded: nested-public-key)!)
let nestedPayload = "Nested payload".data(using: .utf8)!
let nestedRecipientKey = try RSA(publicKey: Data(base64Encoded: "nested-public-key")!)

let nestedJwe = try JWE(
payload: nestedPayload,
Expand All @@ -161,16 +164,17 @@ let nestedJwe = try JWE(
recipientKey: nestedRecipientKey
)

let outerRecipientKey = try RSA(publicKey: Data(base64Encoded: outer-public-key)!)
let outerRecipientKey = try RSA(publicKey: Data(base64Encoded: "outer-public-key")!)
let outerJwe = try JWE(
payload: JSONEncoder().encode(nestedJwe.compactSerialization),
keyManagementAlg: .rsaOAEP,
encryptionAlgorithm: .a256GCM,
recipientKey: outerRecipientKey
)

print(Nested JWE: (outerJwe.compactSerialization))
print("Nested JWE: \(outerJwe.compactSerialization)")
```
Example 3.4

## Conclusion

Expand Down
24 changes: 14 additions & 10 deletions Sources/jose-swift/jose-swift.docc/Articles/JWSSignatures.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,9 @@ let jws = try JWS(
key: key
)

print(JWS: (jws.compactSerialization))
print("JWS: \(jws.compactSerialization)")
```
Example 2.1

In this example, the `JWS` initializer generates a signed JWS using the ES256 algorithm and the provided private key.

Expand All @@ -102,8 +103,9 @@ let publicKey = P256.Signing.PublicKey()
let jws = try JWS(jwsString: jwsString)

let isValid = try jws.verify(key: publicKey)
print(Signature is valid: (isValid))
print("Signature is valid: \(isValid)")
```
Example 2.2

In this example, the `verify` method verifies the JWS using the public key.

Expand All @@ -112,20 +114,21 @@ In this example, the `verify` method verifies the JWS using the public key.
You can include custom headers in your JWS to add additional metadata. Here’s an example:

```swift
let key = secp256k1.Signing.PrivateKey()
let payload = Hello, World!.data(using: .utf8)!
let key = try secp256k1.Signing.PrivateKey()
let payload = "Hello, World!".data(using: .utf8)!

var header = DefaultJWSHeaderImpl(algorithm: .ES256K)
header.keyID = key-id
header.keyID = "key-id"

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

print(JWS: (jws.compactSerialization))
print("JWS: \(jws.compactSerialization)")
```
Example 2.3

In this example, the `kid` (key ID) field is added to the header to specify which key was used for signing.

Expand All @@ -134,8 +137,8 @@ In this example, the `kid` (key ID) field is added to the header to specify whic
A Nested JWS is a JWS that is signed and then signed again. This provides an additional layer of security by ensuring both the integrity and authenticity of the message. Here’s how to create a nested JWS:

```swift
let nestedKey = RSA(keySize: 1228)
let nestedPayload = Nested payload.data(using: .utf8)!
let nestedKey = try RSA(keySize: 1228)
let nestedPayload = "Nested payload".data(using: .utf8)!

let nestedHeader = DefaultJWSHeaderImpl(algorithm: .RS512)
let nestedJws = try JWS(
Expand All @@ -145,15 +148,16 @@ let nestedJws = try JWS(
)

let outerKey = P521.Signing.PrivateKey()
let outerHeader = DefaultJWSHeaderImpl(algorithm: .ES512, contentType: JWT)
let outerHeader = DefaultJWSHeaderImpl(algorithm: .ES512, contentType: "JWT")
let outerJws = try JWS(
payload: JSONEncoder().encode(nestedJws.compactSerialization),
protectedHeader: outerHeader,
key: outerKey
)

print(Nested JWS: (outerJws.compactSerialization))
print("Nested JWS: \(outerJws.compactSerialization)")
```
Example 2.4

## Conclusion

Expand Down
66 changes: 49 additions & 17 deletions Sources/jose-swift/jose-swift.docc/Articles/JWTConcepts.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@ Example:

```
{
sub”: “1234567890,
name”: “John Doe,
admin: true
"sub": "1234567890",
"name": "John Doe",
"admin": true
}
```

Expand All @@ -48,7 +48,7 @@ To create the signature part, you have to take the encoded header, the encoded p
For example, if you want to use the HMAC SHA256 algorithm, the signature will be created in the following way:

```
HMACSHA256(base64UrlEncode(header) + “.” + base64UrlEncode(payload),secret)
HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload),secret)
```

## How JWTs Work
Expand Down Expand Up @@ -82,35 +82,38 @@ Here's an example of how to create a signed JWT using the **jose-swift** library
```swift
let key = P256.Signing.PrivateKey()
let jwt = try JWT.signed(
payload: {
IssuerClaim(value: your-issuer)
SubjectClaim(value: your-subject)
claims: {
IssuerClaim(value: "your-issuer")
SubjectClaim(value: "your-subject")
ExpirationTimeClaim(value: Date().addingTimeInterval(3600)) // 1 hour expiration
},
protectedHeader: DefaultJWSHeaderImpl(algorithm: .ES256),
key: key.jwkRepresentation
)

print(JWT: (jwt.jwtString))
print("JWT: \(jwt.jwtString)")
```
Example 4.1

### Verifying a JWT

Here's an example of how to verify a JWT using the **jose-swift** library:

```swift
let jwtString = your.jwt.token.here
let jwtString = "your.jwt.token.here"
let key = P256.Signing.PublicKey()
let verifiedJWT = try JWT.verify(jwtString: jwtString, signerKey: key)

print(Verified JWT Payload: (verifiedJWT.payload))
print("Verified JWT Payload: \(verifiedJWT.payload)")
```
Example 4.2

### Using Custom Claims

You can also define and use custom claims in your JWTs. Here's an example:

```swift
struct DemoError: Error {}
struct CustomClaims: JWTRegisteredFieldsClaims, Codable {
let iss: String?
let sub: String?
Expand All @@ -120,41 +123,70 @@ struct CustomClaims: JWTRegisteredFieldsClaims, Codable {
let iat: Date?
let jti: String?
let customClaim: String

init(
iss: String? = nil,
sub: String? = nil,
aud: [String]? = nil,
exp: Date? = nil,
nbf: Date? = nil,
iat: Date? = nil,
jti: String? = nil,
customClaim: String
) {
self.iss = iss
self.sub = sub
self.aud = aud
self.exp = exp
self.nbf = nbf
self.iat = iat
self.jti = jti
self.customClaim = customClaim
}

func validateExtraClaims() throws {
// Any extra validation
guard customClaim == "custom-value" else {
throw DemoError()
}
}
}

let key = P256.Signing.PrivateKey()
let claims = CustomClaims(iss: your-issuer, sub: your-subject”, custom: “custom-value)
let claims = CustomClaims(iss: "your-issuer", sub: "your-subject", customClaim: "custom-value")

let jwt = try JWT.signed(
payload: claims,
protectedHeader: DefaultJWSHeaderImpl(algorithm: .ES256),
key: key
)
```
Example 4.3

Or through the DSL API. Here's an example:

```swift
let jwt = try JWT.signed(
payload: {
IssuerClaim(value: your-issuer)
SubjectClaim(value: your-subject)
claims: {
IssuerClaim(value: "your-issuer")
SubjectClaim(value: "your-subject")
ExpirationTimeClaim(value: Date().addingTimeInterval(3600)) // 1 hour expiration
ObjectClaim(key: "address") {
StringClaim(key: "street", value: "Rua Sesamo")
NumberClaim(key: "buildingNumber", value: 1)
BoolClaim(key: "isBuilding", value: true)
}
ArrayClaim(key: "nickNames") {
.string("Me")
.string("Myself")
.string("I")
ArrayElementClaim.string("Me")
ArrayElementClaim.string("Myself")
ArrayElementClaim.string("I")
}
},
protectedHeader: DefaultJWSHeaderImpl(algorithm: .ES256),
key: key.jwkRepresentation
)
```
Example 4.4

## Conclusion

Expand Down
Loading

0 comments on commit a263b8e

Please sign in to comment.