Fix seed generation, add code signing and fix Base64

This commit is contained in:
William Oldham 2023-11-05 10:36:06 +00:00
parent df85861cf2
commit 791923e78c
5 changed files with 32 additions and 32 deletions

View File

@ -7,6 +7,7 @@
"@formkit/auto-animate": "^0.7.0",
"@headlessui/react": "^1.5.0",
"@movie-web/providers": "^1.0.4",
"@noble/hashes": "^1.3.2",
"@react-spring/web": "^9.7.1",
"@scure/bip39": "^1.2.1",
"@sozialhelden/ietf-language-tags": "^5.4.2",
@ -33,7 +34,6 @@
"react-use": "^17.4.0",
"slugify": "^1.6.6",
"subsrt-ts": "^2.1.1",
"universal-base64url": "^1.1.0",
"unzipit": "^1.4.3",
"zustand": "^4.3.9"
},

View File

@ -20,6 +20,9 @@ dependencies:
'@movie-web/providers':
specifier: ^1.0.4
version: 1.0.4
'@noble/hashes':
specifier: ^1.3.2
version: 1.3.2
'@react-spring/web':
specifier: ^9.7.1
version: 9.7.3(react-dom@17.0.2)(react@17.0.2)
@ -98,9 +101,6 @@ dependencies:
subsrt-ts:
specifier: ^2.1.1
version: 2.1.1
universal-base64url:
specifier: ^1.1.0
version: 1.1.0
unzipit:
specifier: ^1.4.3
version: 1.4.3
@ -6150,16 +6150,6 @@ packages:
crypto-random-string: 2.0.0
dev: true
/universal-base64@2.1.0:
resolution: {integrity: sha512-WeOkACVnIXJZr/qlv7++Rl1zuZOHN96v2yS5oleUuv8eJOs5j9M5U3xQEIoWqn1OzIuIcgw0fswxWnUVGDfW6g==}
dev: false
/universal-base64url@1.1.0:
resolution: {integrity: sha512-qWv2+8KCaAWdpqqXwU8W0Yj9pflYDXP37/a3kec6Y4Je7bYzgIfxEVRjZWeLR67be7iot1lGCy5Nuo+xB0fojA==}
dependencies:
universal-base64: 2.1.0
dev: false
/universalify@0.2.0:
resolution: {integrity: sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==}
engines: {node: '>= 4.0.0'}

View File

@ -1,13 +1,14 @@
import { pbkdf2Async } from "@noble/hashes/pbkdf2";
import { sha256 } from "@noble/hashes/sha256";
import { generateMnemonic } from "@scure/bip39";
import { wordlist } from "@scure/bip39/wordlists/english";
import forge from "node-forge";
import { encode } from "universal-base64url";
async function seedFromMnemonic(mnemonic: string) {
const md = forge.md.sha256.create();
md.update(mnemonic);
// TODO this is probably not correct
return md.digest().toHex();
return pbkdf2Async(sha256, mnemonic, "mnemonic", {
c: 2048,
dkLen: 32,
});
}
export async function keysFromMenmonic(mnemonic: string) {
@ -28,13 +29,19 @@ export function genMnemonic(): string {
}
export async function signCode(
_code: string,
_privateKey: forge.pki.ed25519.NativeBuffer
): Promise<Uint8Array> {
// TODO add real signature
return new Uint8Array();
code: string,
privateKey: forge.pki.ed25519.NativeBuffer
): Promise<forge.pki.ed25519.NativeBuffer> {
return forge.pki.ed25519.sign({
encoding: "utf8",
message: code,
privateKey,
});
}
export function bytesToBase64Url(bytes: Uint8Array): string {
return encode(String.fromCodePoint(...bytes));
return btoa(String.fromCodePoint(...bytes))
.replace(/\//g, "_")
.replace(/\+/g, "-")
.replace(/=+$/, "");
}

View File

@ -1,7 +1,11 @@
import { ofetch } from "ofetch";
import { SessionResponse, UserResponse } from "@/backend/accounts/auth";
import { keysFromMenmonic, signCode } from "@/backend/accounts/crypto";
import {
bytesToBase64Url,
keysFromMenmonic as keysFromMnemonic,
signCode,
} from "@/backend/accounts/crypto";
export interface ChallengeTokenResponse {
challenge: string;
@ -55,10 +59,10 @@ export async function registerAccount(
}
export async function signChallenge(mnemonic: string, challengeCode: string) {
const keys = await keysFromMenmonic(mnemonic);
const keys = await keysFromMnemonic(mnemonic);
const signature = await signCode(challengeCode, keys.privateKey);
return {
publicKey: keys.publicKey,
signature,
publicKey: bytesToBase64Url(keys.publicKey),
signature: bytesToBase64Url(signature),
};
}

View File

@ -1,7 +1,6 @@
import { useState } from "react";
import { useAsyncFn } from "react-use";
import { bytesToBase64Url } from "@/backend/accounts/crypto";
import {
getRegisterChallengeToken,
registerAccount,
@ -37,9 +36,9 @@ export function VerifyPassphrase(props: VerifyPassphraseProps) {
const registerResult = await registerAccount(url, {
challenge: {
code: challenge,
signature: bytesToBase64Url(keys.signature),
signature: keys.signature,
},
publicKey: bytesToBase64Url(keys.publicKey),
publicKey: keys.publicKey,
device: props.profile.device,
profile: props.profile.profile,
});