You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 16:40:22