feat: add crypto module (Ed25519 key generation, sign, verify)
Moves verifySignature, signMessage, generateKeyPair and utility functions from Yonexus.Client into Protocol so Server no longer depends on Client at build time or runtime.
This commit is contained in:
49
src/crypto.ts
Normal file
49
src/crypto.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
import { randomBytes, generateKeyPair as _generateKeyPair, sign, verify } from "node:crypto";
|
||||
|
||||
export interface KeyPair {
|
||||
readonly privateKey: string;
|
||||
readonly publicKey: string;
|
||||
readonly algorithm: "Ed25519";
|
||||
}
|
||||
|
||||
export async function generateKeyPair(): Promise<KeyPair> {
|
||||
const { publicKey, privateKey } = await new Promise<{ publicKey: string; privateKey: string }>((resolve, reject) => {
|
||||
_generateKeyPair(
|
||||
"ed25519",
|
||||
{
|
||||
publicKeyEncoding: { type: "spki", format: "pem" },
|
||||
privateKeyEncoding: { type: "pkcs8", format: "pem" },
|
||||
},
|
||||
(err, pubKey, privKey) => (err ? reject(err) : resolve({ publicKey: pubKey, privateKey: privKey }))
|
||||
);
|
||||
});
|
||||
return { privateKey, publicKey, algorithm: "Ed25519" };
|
||||
}
|
||||
|
||||
export async function signMessage(privateKeyPem: string, message: Buffer | string): Promise<string> {
|
||||
return sign(null, typeof message === "string" ? Buffer.from(message) : message, privateKeyPem).toString("base64");
|
||||
}
|
||||
|
||||
export async function verifySignature(publicKeyPem: string, message: Buffer | string, signature: string): Promise<boolean> {
|
||||
try {
|
||||
return verify(null, typeof message === "string" ? Buffer.from(message) : message, publicKeyPem, Buffer.from(signature, "base64"));
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export function generatePairingCode(): string {
|
||||
const bytes = randomBytes(8);
|
||||
const chars = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789";
|
||||
let code = "";
|
||||
for (let i = 0; i < 12; i++) code += chars[bytes[i % bytes.length] % chars.length];
|
||||
return `${code.slice(0, 4)}-${code.slice(4, 8)}-${code.slice(8, 12)}`;
|
||||
}
|
||||
|
||||
export function generateSecret(): string {
|
||||
return randomBytes(32).toString("base64url");
|
||||
}
|
||||
|
||||
export function generateNonce(): string {
|
||||
return randomBytes(18).toString("base64url").slice(0, 24);
|
||||
}
|
||||
@@ -2,3 +2,4 @@ export * from "./types.js";
|
||||
export * from "./codec.js";
|
||||
export * from "./errors.js";
|
||||
export * from "./auth.js";
|
||||
export * from "./crypto.js";
|
||||
|
||||
Reference in New Issue
Block a user