Skip to content

Instantly share code, notes, and snippets.

@Justicea83
Created August 14, 2024 19:24
Show Gist options
  • Save Justicea83/1abe3edeb35ba83669c1eca80a7eb11f to your computer and use it in GitHub Desktop.
Save Justicea83/1abe3edeb35ba83669c1eca80a7eb11f to your computer and use it in GitHub Desktop.
JWT Library
import Array "mo:base/Array";
import Blob "mo:base/Blob";
import Buffer "mo:base/Buffer";
import Nat8 "mo:base/Nat8";
import Text "mo:base/Text";
import Time "mo:base/Time";
import Base64 "mo:encoding/Base64";
import JSON "mo:json/JSON";
import CRC32 "mo:hash/CRC32";
actor JWTLibrary {
// Define the interface for the management canister
type IC = actor {
sign_with_ecdsa : ({
message_hash : Blob;
derivation_path : [Blob];
key_id : { curve: { #secp256k1; } ; name: Text };
}) -> async ({ signature : Blob });
ecdsa_public_key : ({
canister_id : ?Principal;
derivation_path : [Blob];
key_id : { curve: { #secp256k1; } ; name: Text };
}) -> async ({ public_key : Blob; chain_code : Blob; });
};
let ic : IC = actor("aaaaa-aa");
// JWT Header
private func createHeader() : Text {
let header = {
alg = "ES256";
typ = "JWT";
};
Base64.encode(Text.encodeUtf8(JSON.show(#Object(header))));
};
// JWT Payload
private func createPayload(subject : Text, expiresIn : Nat) : async Text {
let now = Time.now();
let payload = {
sub = subject;
iat = now;
exp = now + expiresIn;
};
Base64.encode(Text.encodeUtf8(JSON.show(#Object(payload))));
};
// Sign the JWT
private func signJWT(message : Text) : async Blob {
let messageHash = Blob.fromArray(CRC32.crc32(Blob.toArray(Text.encodeUtf8(message))));
let { signature } = await ic.sign_with_ecdsa({
message_hash = messageHash;
derivation_path = [];
key_id = { curve = #secp256k1; name = "decide_id_pub_key" };
});
signature
};
// Create JWT
public func createJWT(subject : Text, expiresIn : Nat) : async Text {
let header = createHeader();
let payload = await createPayload(subject, expiresIn);
let message = header # "." # payload;
let signature = await signJWT(message);
message # "." # Base64.encode(Blob.toArray(signature))
};
// Get Public Key
public func getPublicKey() : async Text {
let { public_key } = await ic.ecdsa_public_key({
canister_id = null;
derivation_path = [];
key_id = { curve = #secp256k1; name = "decide_id_pub_key" };
});
Base64.encode(Blob.toArray(public_key))
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment