UNPKG

@synet/core

Version:

Core cryptographic and identity primitives for Synet agents.

145 lines (144 loc) 5.35 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.signMessage = signMessage; exports.verifySignature = verifySignature; const crypto = __importStar(require("node:crypto")); /** * Sign a message with a private key * @param privateKey The private key in PEM format * @param message The message to sign * @returns The signature as a base64 string * @throws {Error} If inputs are invalid or signing fails */ function signMessage(privateKey, message) { try { if (!privateKey || !message) { throw new Error("Invalid input: privateKey and message are required"); } const keyType = detectKeyType(privateKey); if (keyType === "ed25519") { // Use the modern API for Ed25519 const signature = crypto.sign(null, Buffer.from(message), { key: privateKey, format: "pem", }); return signature.toString("base64"); } // Use the traditional API for RSA const sign = crypto.createSign("SHA256"); sign.update(message); sign.end(); return sign.sign(privateKey, "base64"); } catch (error) { //console.error("Error signing message:", error); if (error instanceof Error) { throw new Error(`Failed to sign message: ${error.message}`); } throw new Error("Failed to sign message: Unknown error"); } } /** * Verify a signature with a public key * @param publicKey The public key in PEM format * @param message The original message * @param signature The signature to verify (base64 string) * @returns True if the signature is valid, false otherwise * @throws {Error} If inputs are invalid or signing fails */ function verifySignature(publicKey, message, signature) { if (!publicKey || !message || !signature) { throw new Error("Invalid input: publicKey, message and signature are required"); } if (!publicKey.includes("-----BEGIN") || !publicKey.includes("-----END")) { throw new Error("Invalid publicKey format: PEM format required"); } try { const keyType = detectKeyType(publicKey); if (keyType === "ed25519") { // Use the modern API for Ed25519 return crypto.verify(null, Buffer.from(message), { key: publicKey, format: "pem", }, Buffer.from(signature, "base64")); } // Use the traditional API for RSA const verify = crypto.createVerify("SHA256"); verify.update(message); verify.end(); return verify.verify(publicKey, signature, "base64"); } catch (error) { console.error("Error signing message:", error); if (error instanceof Error) { throw new Error(`Failed to verify signature: ${error.message}`); } throw new Error("Failed to verify signature: Unknown error"); } } /** * Detects the type of key based on its PEM content * @param key The key in PEM format * @returns 'rsa' or 'ed25519' */ function detectKeyType(key) { try { // For ED25519 keys in PKCS#8 format, the key is shorter // RSA keys are much longer due to their modulus const keyObj = crypto.createPublicKey({ key: key, format: "pem", }); const keyType = keyObj.asymmetricKeyType; if (keyType === "ed25519") { return "ed25519"; } return "rsa"; } catch (_e) { // If we can't create a key object, try some heuristics if (key.includes("BEGIN PRIVATE KEY") && key.length < 400) { // ED25519 private keys are much shorter than RSA return "ed25519"; } if (key.includes("BEGIN PUBLIC KEY") && key.length < 300) { // ED25519 public keys are much shorter than RSA return "ed25519"; } // Default to RSA as fallback return "rsa"; } }