This repository has been archived by the owner on Sep 4, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Create P256 keypairs for dpop (#29)
* * Create P256 keypairs for dpop * Create jwt * code clean up * code clean up
- Loading branch information
Showing
5 changed files
with
255 additions
and
79 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
// | ||
// File.swift | ||
// | ||
// | ||
// Created by Wentao Liu on 7/11/23. | ||
// | ||
|
||
import Foundation | ||
import CryptoKit | ||
|
||
|
||
func base64UrlEncoded(_ data: Data) -> String { | ||
var b64 = data.base64EncodedString() | ||
b64 = b64.replacingOccurrences(of: "+", with: "-") | ||
b64 = b64.replacingOccurrences(of: "/", with: "_") | ||
b64 = b64.replacingOccurrences(of: "=", with: "") | ||
return b64 | ||
} | ||
|
||
func createJwt() -> String?{ | ||
var error: Unmanaged<CFError>? | ||
|
||
do { | ||
let privateKey = try retrieveKeyFromKeyChain() | ||
|
||
// Get the public key. | ||
let publicKey = privateKey.publicKey | ||
|
||
// Get the raw representation of the public key. | ||
let rawPublicKey = publicKey.rawRepresentation | ||
|
||
// Extract the x and y coordinates. | ||
let xCoordinateData = rawPublicKey[1..<33] | ||
let yCoordinateData = rawPublicKey[33..<65] | ||
|
||
// If you need base64-encoded strings for JWK: | ||
let xCoordinateBase64 = base64UrlEncoded(xCoordinateData) | ||
let yCoordinateBase64 = base64UrlEncoded(yCoordinateData) | ||
// Convert the public key to JWK format. | ||
// construct headers | ||
var headers: [String: Any] = ["typ": "dpop+jwt", "alg": "ES256"] | ||
headers["jwk"] = [ | ||
"kty": "EC", | ||
"crv": "P-256", | ||
"x": xCoordinateBase64, | ||
"y": yCoordinateBase64 | ||
] as [String : Any] | ||
|
||
let headersData = try JSONSerialization.data(withJSONObject: headers) | ||
let headersB64 = base64UrlEncoded(headersData) | ||
|
||
|
||
// construct claims | ||
let iat = Int(Date().timeIntervalSince1970) | ||
let jti = UUID().uuidString.lowercased() | ||
|
||
let claims: [String: Any] = ["iat": iat, "jti": jti] | ||
let claimsData = try JSONSerialization.data(withJSONObject: claims) | ||
let claimsB64 = base64UrlEncoded(claimsData) | ||
|
||
/// sign | ||
let signingInput = headersB64 + "." + claimsB64 | ||
let signingInputData = signingInput.data(using: .utf8)! | ||
|
||
let signature = try! privateKey.signature(for: signingInputData) | ||
|
||
let signatureB64 = base64UrlEncoded(signature.rawRepresentation) | ||
|
||
let jwt = signingInput + "." + signatureB64 | ||
|
||
return jwt | ||
|
||
} catch { | ||
// silently handled error | ||
return nil | ||
} | ||
|
||
} | ||
|
Oops, something went wrong.