如何从Uint8Array生成WebCrypto的CryptoKeyPair?
从Uint8Array的Ed25519私钥生成WebCrypto CryptoKeyPair的正确方法
问题1:密钥使用权限错误的解决
Ed25519算法的私钥仅支持sign操作,公钥仅支持verify操作,不能给私钥同时指定sign和verify权限——这是你收到"Unsupported key usage for a Ed25519 key"错误的核心原因。
问题2:从私钥推导公钥的方法
WebCrypto API没有直接从私钥对象提取公钥的内置方法,但可以通过「导出私钥原始数据→提取公钥片段→导入为公钥对象」的流程实现:
Ed25519的标准私钥格式通常是64字节(前32字节是私钥种子,后32字节是对应的公钥),即使你传入的是32字节的种子,WebCrypto导入后导出的原始数据也会自动补全为64字节格式。
修正后的完整代码
import { webcrypto } from "node:crypto"; const RANDOM_PRIVATE_KEY_DO_NOT_USE = new Uint8Array([ 144, 194, 221, 213, 246, 54, 246, 208, 227, 91, 76, 237, 35, 137, 98, 221, 82, 87, 49, 240, 137, 166, 174, 39, 208, 143, 252, 120, 182, 49, 102, 139, 134, 105, 228, 183, 34, 22, 11, 174, 73, 2, 12, 84, 231, 64, 186, 51, 148, 2, 41, 156, 137, 53, 56, 50, 0, 0, 183, 237, 67, 157, 149, 110, ]); async function privateKeyBytesToKeyPair( privateKeyBytes: Uint8Array ): Promise<CryptoKeyPair> { // 1. 导入私钥:仅指定sign权限 const privateKey = await webcrypto.subtle.importKey( "raw", privateKeyBytes, { name: "Ed25519" }, true, ["sign"] ); // 2. 导出私钥的原始格式数据,提取后32字节作为公钥原始数据 const privateKeyRaw = new Uint8Array( await webcrypto.subtle.exportKey("raw", privateKey) ); const publicKeyBytes = privateKeyRaw.slice(32); // 3. 导入公钥:指定verify权限 const publicKey = await webcrypto.subtle.importKey( "raw", publicKeyBytes, { name: "Ed25519" }, true, ["verify"] ); return { privateKey, publicKey }; } const keyPair = await privateKeyBytesToKeyPair(RANDOM_PRIVATE_KEY_DO_NOT_USE); console.log("Key pair:", keyPair);
内容的提问来源于stack exchange,提问作者mikemaccana
相关产品推荐
相关产品推荐

