passkey test #116
@@ -7,7 +7,7 @@ import { sha256 } from "ethereum-cryptography/sha256.js";
|
||||
import { bytesToMultibase } from "@veramo/utils";
|
||||
import {
|
||||
startAuthentication,
|
||||
startRegistration,
|
||||
startRegistration, WebAuthnAbortService,
|
||||
} from "@simplewebauthn/browser";
|
||||
import {
|
||||
generateAuthenticationOptions,
|
||||
@@ -207,55 +207,33 @@ export class PeerSetup {
|
||||
public signature?: Base64URLString;
|
||||
public publicKeyJwk?: JWK;
|
||||
|
||||
public async createJwt(
|
||||
payload: object,
|
||||
issuerDid: string,
|
||||
credentialId: string,
|
||||
) {
|
||||
public async createJwt(fullPayload: object, credentialId: string) {
|
||||
const header: JWTPayload = { typ: "JWT", alg: "ES256" };
|
||||
|
||||
// from createJWT in did-jwt/src/JWT.ts
|
||||
const timestamps: Partial<JWTPayload> = {
|
||||
iat: Math.floor(Date.now() / 1000),
|
||||
exp: undefined,
|
||||
};
|
||||
const fullPayload = { ...timestamps, ...payload, iss: issuerDid };
|
||||
|
||||
const payloadHash: Uint8Array = sha256(
|
||||
Buffer.from(JSON.stringify(fullPayload)),
|
||||
);
|
||||
this.challenge = new Uint8Array(Buffer.from(JSON.stringify(fullPayload)));
|
||||
// const payloadHash: Uint8Array = sha256(this.challenge);
|
||||
const options: PublicKeyCredentialRequestOptionsJSON =
|
||||
await generateAuthenticationOptions({
|
||||
challenge: payloadHash,
|
||||
challenge: this.challenge,
|
||||
rpID: window.location.hostname,
|
||||
// Require users to use a previously-registered authenticator
|
||||
// allowCredentials: userPasskeys.map(passkey => ({
|
||||
// id: passkey.id,
|
||||
// transports: passkey.transports,
|
||||
// })),
|
||||
});
|
||||
console.log("custom authentication options", options);
|
||||
// console.log("simple authentication options", options);
|
||||
|
||||
const clientAuth = await startAuthentication(options);
|
||||
console.log("custom clientAuth", clientAuth);
|
||||
// console.log("simple credential get", clientAuth);
|
||||
|
||||
this.authenticatorDataBase64Url = clientAuth.response.authenticatorData;
|
||||
this.authenticatorData = Buffer.from(
|
||||
clientAuth.response.authenticatorData,
|
||||
"base64",
|
||||
).buffer;
|
||||
this.challenge = payloadHash;
|
||||
this.clientDataJsonBase64Url = clientAuth.response.clientDataJSON;
|
||||
this.clientDataJsonDecoded = JSON.parse(
|
||||
Buffer.from(clientAuth.response.clientDataJSON, "base64").toString(
|
||||
"utf-8",
|
||||
),
|
||||
);
|
||||
console.log("authenticatorData for signing", this.authenticatorData);
|
||||
console.log(
|
||||
"clientDataJSON for signing",
|
||||
Buffer.from(clientAuth.response.clientDataJSON, "base64"),
|
||||
);
|
||||
//console.log("simple authenticatorData for signing", this.authenticatorData);
|
||||
this.signature = clientAuth.response.signature;
|
||||
|
||||
const headerBase64 = Buffer.from(JSON.stringify(header)).toString("base64");
|
||||
@@ -265,25 +243,90 @@ export class PeerSetup {
|
||||
return headerBase64 + "." + payloadBase64 + "." + signature;
|
||||
}
|
||||
|
||||
public async createJwt2(
|
||||
payload: object,
|
||||
issuerDid: string,
|
||||
credentialId: string,
|
||||
) {
|
||||
const signer = await this.webAuthnES256KSigner(credentialId);
|
||||
public async createJwt2(fullPayload: object, credentialId: string) {
|
||||
const header: JWTPayload = { typ: "JWT", alg: "ES256" };
|
||||
const headerBase64 = Buffer.from(JSON.stringify(header)).toString("base64");
|
||||
|
||||
// from createJWT in did-jwt/src/JWT.ts
|
||||
const header: JWTPayload = { typ: "JWT", alg: "ES256K" };
|
||||
const timestamps: Partial<JWTPayload> = {
|
||||
iat: Math.floor(Date.now() / 1000),
|
||||
exp: undefined,
|
||||
const dataToSignString = JSON.stringify(fullPayload);
|
||||
const dataToSignBuffer = Buffer.from(dataToSignString);
|
||||
|
||||
//console.log("lower credentialId", credentialId);
|
||||
this.challenge = new Uint8Array(dataToSignBuffer);
|
||||
const options = {
|
||||
publicKey: {
|
||||
challenge: this.challenge.buffer,
|
||||
rpID: window.location.hostname,
|
||||
//allowCredentials: [{ id: credentialId, type: "public-key" }],
|
||||
userVerification: "preferred",
|
||||
//extensions: fullPayload,
|
||||
},
|
||||
};
|
||||
const fullPayload = { ...timestamps, ...payload, iss: issuerDid };
|
||||
|
||||
const jwt = createJWS(fullPayload, signer, header);
|
||||
// console.log("lower authentication options", options);
|
||||
// console.log("lower options in base64", {
|
||||
// publicKey: {
|
||||
// challenge: bufferToBase64URLString(options.publicKey.challenge),
|
||||
// rpID: window.location.hostname,
|
||||
// userVerification: "preferred",
|
||||
// },
|
||||
// });
|
||||
const credential = await navigator.credentials.get(options);
|
||||
// console.log("lower credential get", credential);
|
||||
// console.log("lower credential get in base64", {
|
||||
// id: credential?.id,
|
||||
// rawId: bufferToBase64URLString(credential?.rawId),
|
||||
// response: {
|
||||
// authenticatorData: bufferToBase64URLString(
|
||||
// credential?.response.authenticatorData,
|
||||
// ),
|
||||
// clientDataJSON: bufferToBase64URLString(
|
||||
// credential?.response.clientDataJSON,
|
||||
// ),
|
||||
// signature: bufferToBase64URLString(credential?.response.signature),
|
||||
// },
|
||||
// type: credential?.type,
|
||||
// });
|
||||
|
||||
const authenticatorAssertionResponse = credential?.response;
|
||||
|
||||
this.authenticatorDataBase64Url =
|
||||
authenticatorAssertionResponse.authenticatorData;
|
||||
this.authenticatorData = Buffer.from(
|
||||
this.authenticatorDataBase64Url as Base64URLString,
|
||||
"base64",
|
||||
).buffer;
|
||||
// console.log("lower authenticator data", this.authenticatorData);
|
||||
|
||||
this.clientDataJsonBase64Url =
|
||||
authenticatorAssertionResponse.clientDataJSON;
|
||||
this.clientDataJsonDecoded = JSON.parse(
|
||||
new TextDecoder("utf-8").decode(
|
||||
authenticatorAssertionResponse.clientDataJSON,
|
||||
),
|
||||
);
|
||||
// console.log("lower clientDataJSON decoded", this.clientDataJsonDecoded);
|
||||
|
||||
const origSignature = Buffer.from(
|
||||
authenticatorAssertionResponse.signature,
|
||||
).toString("base64");
|
||||
this.signature = origSignature
|
||||
.replace(/\+/g, "-")
|
||||
.replace(/\//g, "_")
|
||||
.replace(/=+$/, "");
|
||||
|
||||
const dataInJwt = {
|
||||
AuthenticationData: this.authenticatorDataBase64Url,
|
||||
ClientDataJSON: this.clientDataJsonBase64Url,
|
||||
};
|
||||
const dataInJwtString = JSON.stringify(dataInJwt);
|
||||
const payloadBase64 = Buffer.from(dataInJwtString).toString("base64");
|
||||
const jwt = headerBase64 + "." + payloadBase64 + "." + this.signature;
|
||||
return jwt;
|
||||
}
|
||||
|
||||
// Attempted with JWS, but it will not match because it signs different content (header + payload)
|
||||
//const signer = await this.webAuthnES256KSigner(credentialId);
|
||||
//const jwt = createJWS(fullPayload, signer, { typ: "JWT", alg: "ES256" });
|
||||
async webAuthnES256KSigner(credentialID: string) {
|
||||
return async (data: string | Uint8Array) => {
|
||||
const signature = await this.generateWebAuthnSignature(
|
||||
@@ -293,22 +336,23 @@ export class PeerSetup {
|
||||
|
||||
// This converts from the browser ArrayBuffer to a Node.js Buffer, which is a requirement for the asn1 library.
|
||||
const signatureBuffer = Buffer.from(signature);
|
||||
console.log("signature inside signer", signature);
|
||||
console.log("buffer signature inside signer", signatureBuffer);
|
||||
console.log("lower signature inside signer", signature);
|
||||
console.log("lower buffer signature inside signer", signatureBuffer);
|
||||
console.log("lower base64 buffer signature inside signer", signatureBuffer.toString("base64"));
|
||||
// Decode the DER-encoded signature to extract R and S values
|
||||
const reader = new asn1.BerReader(signatureBuffer);
|
||||
console.log("after reader");
|
||||
console.log("lower after reader");
|
||||
reader.readSequence();
|
||||
console.log("after read sequence");
|
||||
console.log("lower after read sequence");
|
||||
const r = reader.readString(asn1.Ber.Integer, true);
|
||||
console.log("after r");
|
||||
console.log("lower after r");
|
||||
const s = reader.readString(asn1.Ber.Integer, true);
|
||||
console.log("after r & s");
|
||||
console.log("lower after r & s");
|
||||
|
||||
// Ensure R and S are 32 bytes each
|
||||
const rBuffer = Buffer.from(r);
|
||||
const sBuffer = Buffer.from(s);
|
||||
console.log("after rBuffer & sBuffer", rBuffer, sBuffer);
|
||||
console.log("lower after rBuffer & sBuffer", rBuffer, sBuffer);
|
||||
const rWithoutPrefix = rBuffer.length > 32 ? rBuffer.slice(1) : rBuffer;
|
||||
const sWithoutPrefix = sBuffer.length > 32 ? sBuffer.slice(1) : sBuffer;
|
||||
const rPadded =
|
||||
@@ -323,18 +367,18 @@ export class PeerSetup {
|
||||
// Concatenate R and S to form the 64-byte array (ECDSA signature format expected by JWT)
|
||||
const combinedSignature = Buffer.concat([rPadded, sPadded]);
|
||||
console.log(
|
||||
"combinedSignature",
|
||||
"lower combinedSignature",
|
||||
combinedSignature.length,
|
||||
combinedSignature,
|
||||
);
|
||||
|
||||
const combSig64 = combinedSignature.toString("base64");
|
||||
console.log("combSig64", combSig64);
|
||||
console.log("lower combSig64", combSig64);
|
||||
const combSig64Url = combSig64
|
||||
.replace(/\+/g, "-")
|
||||
.replace(/\//g, "_")
|
||||
.replace(/=+$/, "");
|
||||
console.log("combSig64Url", combSig64Url);
|
||||
console.log("lower combSig64Url", combSig64Url);
|
||||
return combSig64Url;
|
||||
};
|
||||
}
|
||||
@@ -343,30 +387,50 @@ export class PeerSetup {
|
||||
dataToSign: string | Uint8Array, // from Signer interface
|
||||
credentialId: string,
|
||||
) {
|
||||
if (dataToSign instanceof Uint8Array) {
|
||||
dataToSign = new TextDecoder("utf-8").decode(dataToSign as Uint8Array);
|
||||
if (!(dataToSign instanceof Uint8Array)) {
|
||||
console.log("lower dataToSign & typeof ", typeof dataToSign, dataToSign);
|
||||
dataToSign = new Uint8Array(base64URLStringToBuffer(dataToSign));
|
||||
}
|
||||
|
||||
console.log("credentialId", credentialId);
|
||||
console.log("lower credentialId", credentialId);
|
||||
this.challenge = dataToSign;
|
||||
const options = {
|
||||
challenge: new TextEncoder().encode(dataToSign).buffer,
|
||||
//allowCredentials: [{ id: credentialId, type: "public-key" }],
|
||||
userVerification: "preferred",
|
||||
publicKey: {
|
||||
challenge: this.challenge.buffer,
|
||||
rpID: window.location.hostname,
|
||||
//allowCredentials: [{ id: credentialId, type: "public-key" }],
|
||||
userVerification: "preferred",
|
||||
//extensions: fullPayload,
|
||||
},
|
||||
};
|
||||
|
||||
const assertion = await navigator.credentials.get({ publicKey: options });
|
||||
console.log("assertion", assertion);
|
||||
// console.log("lower authentication options", options);
|
||||
const assertion = await navigator.credentials.get(options);
|
||||
// console.log("lower credential get", assertion);
|
||||
|
||||
const authenticatorAssertionResponse = assertion?.response;
|
||||
|
||||
this.authenticatorDataBase64Url =
|
||||
authenticatorAssertionResponse.authenticatorData;
|
||||
this.authenticatorData = Buffer.from(
|
||||
this.authenticatorDataBase64Url as Base64URLString,
|
||||
"base64",
|
||||
).buffer;
|
||||
// console.log("lower authenticator data", this.authenticatorData);
|
||||
|
||||
this.clientDataJsonBase64Url =
|
||||
authenticatorAssertionResponse.clientDataJSON;
|
||||
this.clientDataJsonDecoded = JSON.parse(
|
||||
new TextDecoder("utf-8").decode(
|
||||
authenticatorAssertionResponse.clientDataJSON,
|
||||
),
|
||||
);
|
||||
console.log("clientDataJSON decoded", this.clientDataJsonDecoded);
|
||||
this.authenticatorData = authenticatorAssertionResponse.authenticatorData;
|
||||
console.log("authenticator data", this.authenticatorData);
|
||||
return authenticatorAssertionResponse.signature;
|
||||
// console.log("lower clientDataJSON decoded", this.clientDataJsonDecoded);
|
||||
|
||||
this.signature = Buffer.from(
|
||||
authenticatorAssertionResponse.signature,
|
||||
).toString("base64");
|
||||
|
||||
return this.signature;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -383,109 +447,34 @@ export async function verifyJwt(
|
||||
publicKeyJwk: JWK,
|
||||
signature: Base64URLString,
|
||||
) {
|
||||
// Here's a combined auth & verify process, based on some of the inputs.
|
||||
//
|
||||
// const options: PublicKeyCredentialRequestOptionsJSON =
|
||||
// await generateAuthenticationOptions({
|
||||
// rpID: window.location.hostname,
|
||||
// // Require users to use a previously-registered authenticator
|
||||
// // allowCredentials: userPasskeys.map(passkey => ({
|
||||
// // id: passkey.id,
|
||||
// // transports: passkey.transports,
|
||||
// // })),
|
||||
// });
|
||||
// console.log("authentication options", options);
|
||||
//
|
||||
// const clientAuth = await startAuthentication(options);
|
||||
// console.log("clientAuth", clientAuth);
|
||||
//
|
||||
// const verfOpts: VerifyAuthenticationResponseOpts = {
|
||||
// const authData = arrayToBase64Url(Buffer.from(authenticatorData));
|
||||
// const authOpts: VerifyAuthenticationResponseOpts = {
|
||||
// authenticator: {
|
||||
// credentialID: credId,
|
||||
// credentialPublicKey: publicKeyBytes,
|
||||
// counter: 0,
|
||||
// },
|
||||
// expectedChallenge: options.challenge,
|
||||
// expectedChallenge: arrayToBase64Url(challenge),
|
||||
// expectedOrigin: window.location.origin,
|
||||
// expectedRPID: window.location.hostname,
|
||||
// response: clientAuth,
|
||||
// response: {
|
||||
// authenticatorAttachment: "platform",
|
||||
// clientExtensionResults: {},
|
||||
// id: credId,
|
||||
// rawId: arrayToBase64Url(rawId),
|
||||
// response: {
|
||||
// authenticatorData: authData,
|
||||
// clientDataJSON: arrayToBase64Url(
|
||||
// Buffer.from(JSON.stringify(clientDataJSON)),
|
||||
// ),
|
||||
// signature: signature,
|
||||
// },
|
||||
// type: "public-key",
|
||||
// },
|
||||
// };
|
||||
// console.log("verfOpts", verfOpts);
|
||||
// const verificationFromClient = await verifyAuthenticationResponse(verfOpts);
|
||||
// console.log("client auth verification", verificationFromClient);
|
||||
|
||||
const authData = arrayToBase64Url(Buffer.from(authenticatorData));
|
||||
const authOpts: VerifyAuthenticationResponseOpts = {
|
||||
authenticator: {
|
||||
credentialID: credId,
|
||||
credentialPublicKey: publicKeyBytes,
|
||||
counter: 0,
|
||||
},
|
||||
expectedChallenge: arrayToBase64Url(challenge),
|
||||
expectedOrigin: window.location.origin,
|
||||
expectedRPID: window.location.hostname,
|
||||
response: {
|
||||
authenticatorAttachment: "platform",
|
||||
clientExtensionResults: {},
|
||||
id: credId,
|
||||
rawId: arrayToBase64Url(rawId),
|
||||
response: {
|
||||
authenticatorData: authData,
|
||||
clientDataJSON: arrayToBase64Url(
|
||||
Buffer.from(JSON.stringify(clientDataJSON)),
|
||||
),
|
||||
signature: signature,
|
||||
},
|
||||
type: "public-key",
|
||||
},
|
||||
};
|
||||
console.log("auth opts", authOpts);
|
||||
const verification = await verifyAuthenticationResponse(authOpts);
|
||||
console.log("auth verification", verification);
|
||||
|
||||
// It doesn't work to use the did-jwt verifyJWT with did-resolver Resolver
|
||||
// const decoded = verifyJWT(jwt, {
|
||||
// resolver: new Resolver({ peer: peerDidToDidDocument }),
|
||||
// });
|
||||
// return decoded;
|
||||
|
||||
// const [headerB64, concatenatedPayloadB64, signatureB64] = jwt.split(".");
|
||||
//
|
||||
// const header = JSON.parse(atob(headerB64));
|
||||
// const jsonPayload = JSON.parse(atob(concatenatedPayloadB64));
|
||||
// const [jsonPayloadB64, otherDataHashB64] = concatenatedPayloadB64.split(".");
|
||||
//
|
||||
// const otherDataHash = base64urlDecode(otherDataHashB64);
|
||||
// const signature = base64urlDecode(signatureB64);
|
||||
//
|
||||
// const dataToVerify = new TextEncoder().encode(`${headerB64}.${concatenatedPayloadB64}`);
|
||||
// const dataHash = await sha256(dataToVerify);
|
||||
//
|
||||
// const authenticatorData = base64urlDecode(jsonPayload.authenticatorData);
|
||||
// const clientDataJSON = jsonPayload.clientDataJSON;
|
||||
|
||||
/////////
|
||||
|
||||
// const clientBuffer = clientDataJsonBase64Url
|
||||
// .replace(/-/g, "+")
|
||||
// .replace(/_/g, "/");
|
||||
// const clientData = new Uint8Array(Buffer.from(clientBuffer, "base64"));
|
||||
// const clientDataHash = sha256(clientData);
|
||||
//
|
||||
// const verifyData = new Uint8Array([
|
||||
// ...new Uint8Array(authenticatorData),
|
||||
// ...new Uint8Array(clientDataHash),
|
||||
// ]);
|
||||
// console.log("verifyData", verifyData);
|
||||
// const sigBase64Raw = signature.replace(/-/g, "+").replace(/_/g, "/");
|
||||
//
|
||||
// const sigHex = new Uint8Array(Buffer.from(sigBase64Raw, "base64")); //Buffer.from(sigBase64Raw, "base64").toString("hex");
|
||||
// const msgHex = verifyData; //new Buffer(verifyData).toString("hex");
|
||||
// const pubHex = publicKeyBytes; //new Buffer(publicKeyBytes).toString("hex");
|
||||
// console.log("sig msg pub", sigHex, msgHex, pubHex);
|
||||
// const isValid = p256.verify(sigHex, msgHex, pubHex);
|
||||
|
||||
/////////
|
||||
// console.log("auth opts", authOpts);
|
||||
// const verification = await verifyAuthenticationResponse(authOpts);
|
||||
// console.log("auth verification", verification);
|
||||
|
||||
const authDataFromBase = Buffer.from(authenticatorDataBase64Url, "base64");
|
||||
const clientDataFromBase = Buffer.from(clientDataJsonBase64Url, "base64");
|
||||
@@ -498,9 +487,9 @@ export async function verifyJwt(
|
||||
// Construct the preimage
|
||||
const preimage = Buffer.concat([authDataFromBase, hash]);
|
||||
|
||||
console.log("finalSigBuffer", finalSigBuffer);
|
||||
console.log("preimage", preimage);
|
||||
console.log("publicKeyBytes", publicKeyBytes);
|
||||
// console.log("finalSigBuffer", finalSigBuffer);
|
||||
// console.log("preimage", preimage);
|
||||
// console.log("publicKeyBytes", publicKeyBytes);
|
||||
|
||||
// This uses p256 from @noble/curves/p256, which I would prefer but it's returning false.
|
||||
// const isValid = p256.verify(
|
||||
@@ -510,8 +499,6 @@ export async function verifyJwt(
|
||||
// );
|
||||
// console.log("isValid", isValid);
|
||||
|
||||
/////////
|
||||
|
||||
const WebCrypto = await getWebCrypto();
|
||||
const verifyAlgorithm = {
|
||||
name: "ECDSA",
|
||||
@@ -521,10 +508,6 @@ export async function verifyJwt(
|
||||
name: "ECDSA",
|
||||
namedCurve: publicKeyJwk.crv,
|
||||
};
|
||||
// const publicKeyCryptoKey = await importKey({
|
||||
// publicKeyJwk,
|
||||
// algorithm: keyAlgorithm,
|
||||
// });
|
||||
const publicKeyCryptoKey = await WebCrypto.subtle.importKey(
|
||||
"jwk",
|
||||
publicKeyJwk,
|
||||
@@ -532,17 +515,17 @@ export async function verifyJwt(
|
||||
false,
|
||||
["verify"],
|
||||
);
|
||||
console.log("verifyAlgorithm", verifyAlgorithm);
|
||||
console.log("publicKeyCryptoKey", publicKeyCryptoKey);
|
||||
console.log("finalSigBuffer", finalSigBuffer);
|
||||
console.log("preimage", preimage);
|
||||
// console.log("verifyAlgorithm", verifyAlgorithm);
|
||||
// console.log("publicKeyCryptoKey", publicKeyCryptoKey);
|
||||
// console.log("finalSigBuffer", finalSigBuffer);
|
||||
// console.log("preimage", preimage);
|
||||
const verified = await WebCrypto.subtle.verify(
|
||||
verifyAlgorithm,
|
||||
publicKeyCryptoKey,
|
||||
finalSigBuffer,
|
||||
preimage,
|
||||
);
|
||||
console.log("verified", verified);
|
||||
// console.log("verified", verified);
|
||||
return verified;
|
||||
}
|
||||
|
||||
@@ -552,7 +535,8 @@ async function peerDidToDidDocument(did: string): Promise<DIDResolutionResult> {
|
||||
"This only verifies a peer DID, method 0, encoded base58btc.",
|
||||
);
|
||||
}
|
||||
// this is basically hard-coded based on the results from the @aviarytech/did-peer resolver
|
||||
// this is basically hard-coded from https://www.w3.org/TR/did-core/#example-various-verification-method-types
|
||||
// (another reference is the @aviarytech/did-peer resolver)
|
||||
const id = did.split(":")[2];
|
||||
const multibase = id.slice(1);
|
||||
const encnumbasis = multibase.slice(1);
|
||||
@@ -617,6 +601,31 @@ function base64urlEncode(buffer: ArrayBuffer) {
|
||||
return btoa(str).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
||||
}
|
||||
|
||||
// from @simplewebauthn/browser
|
||||
function bufferToBase64URLString(buffer) {
|
||||
const bytes = new Uint8Array(buffer);
|
||||
let str = '';
|
||||
for (const charCode of bytes) {
|
||||
str += String.fromCharCode(charCode);
|
||||
}
|
||||
const base64String = btoa(str);
|
||||
return base64String.replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '');
|
||||
}
|
||||
|
||||
// from @simplewebauthn/browser
|
||||
function base64URLStringToBuffer(base64URLString) {
|
||||
const base64 = base64URLString.replace(/-/g, '+').replace(/_/g, '/');
|
||||
const padLength = (4 - (base64.length % 4)) % 4;
|
||||
const padded = base64.padEnd(base64.length + padLength, '=');
|
||||
const binary = atob(padded);
|
||||
const buffer = new ArrayBuffer(binary.length);
|
||||
const bytes = new Uint8Array(buffer);
|
||||
for (let i = 0; i < binary.length; i++) {
|
||||
bytes[i] = binary.charCodeAt(i);
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
function cborToKeys(publicKeyBytes: Uint8Array) {
|
||||
const jwkObj = cborDecode(publicKeyBytes);
|
||||
console.log("jwkObj from verification", jwkObj);
|
||||
|
||||
@@ -210,6 +210,7 @@ import {
|
||||
verifyJwt,
|
||||
} from "@/libs/didPeer";
|
||||
import { Buffer } from "buffer";
|
||||
import {JWTPayload} from "did-jwt";
|
||||
|
||||
const inputFileNameRef = ref<Blob>();
|
||||
|
||||
@@ -222,8 +223,14 @@ export default class Help extends Vue {
|
||||
authenticatorData?: ArrayBuffer;
|
||||
credId?: Base64URLString;
|
||||
jwt?: string;
|
||||
payload = { a: 1 };
|
||||
jwt2?: string;
|
||||
payload = {
|
||||
"@context": "https://schema.org",
|
||||
type: "GiveAction",
|
||||
description: "pizza",
|
||||
};
|
||||
peerSetup?: PeerSetup;
|
||||
peerSetup2?: PeerSetup;
|
||||
publicKeyJwk?: JWK;
|
||||
publicKeyBytes?: Uint8Array;
|
||||
rawId?: Uint8Array;
|
||||
@@ -277,19 +284,40 @@ export default class Help extends Vue {
|
||||
public async create() {
|
||||
console.log("Starting a create");
|
||||
const did = createPeerDid(this.publicKeyBytes as Uint8Array);
|
||||
console.log("did", did);
|
||||
// console.log("did", did);
|
||||
|
||||
// from createJWT in did-jwt/src/JWT.ts
|
||||
const timestamps: Partial<JWTPayload> = {
|
||||
iat: Math.floor(Date.now() / 1000),
|
||||
exp: undefined,
|
||||
};
|
||||
const fullPayload = { ...timestamps, ...this.payload, did };
|
||||
|
||||
this.peerSetup = new PeerSetup();
|
||||
const rawJwt = await this.peerSetup.createJwt(
|
||||
this.payload,
|
||||
did,
|
||||
fullPayload,
|
||||
this.credId as string,
|
||||
);
|
||||
console.log("raw jwt", rawJwt);
|
||||
//console.log("simple raw jwt", rawJwt);
|
||||
this.jwt = rawJwt
|
||||
.replace(/\+/g, "-")
|
||||
.replace(/\//g, "_")
|
||||
.replace(/=+$/, "");
|
||||
console.log("jwt4url", this.jwt);
|
||||
console.log("simple jwt4url", this.jwt);
|
||||
// console.log("simple peerSetup", this.peerSetup);
|
||||
|
||||
this.peerSetup2 = new PeerSetup();
|
||||
const rawJwt2 = await this.peerSetup2.createJwt2(
|
||||
fullPayload,
|
||||
this.credId as string,
|
||||
);
|
||||
// console.log("lower raw jwt2", rawJwt2);
|
||||
this.jwt2 = rawJwt2
|
||||
.replace(/\+/g, "-")
|
||||
.replace(/\//g, "_")
|
||||
.replace(/=+$/, "");
|
||||
console.log("lower jwt4url2", this.jwt2);
|
||||
// console.log("lower peerSetup2", this.peerSetup2);
|
||||
}
|
||||
|
||||
public async verify() {
|
||||
@@ -311,6 +339,21 @@ export default class Help extends Vue {
|
||||
this.peerSetup.signature as Base64URLString,
|
||||
);
|
||||
console.log("decoded", decoded);
|
||||
|
||||
const decoded2 = await verifyJwt(
|
||||
this.jwt2 as string,
|
||||
this.credId as Base64URLString,
|
||||
this.rawId as Uint8Array,
|
||||
this.peerSetup2.authenticatorData as ArrayBuffer,
|
||||
this.peerSetup2.authenticatorDataBase64Url as Base64URLString,
|
||||
this.peerSetup2.challenge as Uint8Array,
|
||||
this.peerSetup2.clientDataJsonDecoded,
|
||||
this.peerSetup2.clientDataJsonBase64Url as Base64URLString,
|
||||
this.publicKeyBytes as Uint8Array,
|
||||
this.publicKeyJwk as JWK,
|
||||
this.peerSetup2.signature as Base64URLString,
|
||||
);
|
||||
console.log("decoded2", decoded2);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user