如何从 Uint8Array 制作 webcrypto CryptoKeyPair?

问题描述 投票:0回答:1

我正在使用 webcrypto API 并拥有存储为

UInt8Array
的有效 Ed25519 私钥。

我想使用

KeyPair
中的私钥。这是我迄今为止的尝试:

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, 231, 67, 157, 149, 110,
]);

async function privateKeyBytesToKeyPair(
  privateKeyBytes: Uint8Array
): Promise<CryptoKeyPair> {
  // Import the private key
  const privateKey = await webcrypto.subtle.importKey(
    "raw",
    privateKeyBytes.buffer,
    {
      name: "Ed25519",
    },
    true,
    // These DO match the 'Algortihm Matrix' section of the WebCrypto API
    // See https://nodejs.org/api/webcrypto.html#subtleimportkeyformat-keydata-algorithm-extractable-keyusages
    // However this fails with "Unsupported key usage for a Ed25519 key"
    ["sign", "verify"]
  );

  const keyPair: CryptoKeyPair = {
    publicKey: "TODO", // The private key is not enough to generate the public key, why do I need this?
    privateKey,
  };

  return keyPair;
}

const keyPair = await privateKeyBytesToKeyPair(RANDOM_PRIVATE_KEY_DO_NOT_USE);
console.log("Key pair:", keyPair);

我遇到了两个问题(也许还有更多):

  • 尽管我的
    usages
    ["sign", "verify"]
    )根据密钥使用矩阵是正确的,但我的导入将失败,并显示:
    Unsupported key usage for a Ed25519 key
  • 创建
    CryptoKeyPair
    时,webcrypto API 希望我在已经可以从私钥派生出公钥时指定公钥。

如何从 Uint8Array 制作 webcrypto CryptoKeyPair?

node.js typescript webcrypto-api webcrypto
1个回答
0
投票

根据本文件,秒。 导入密钥,Ed25519 支持的公钥格式为 spkijwkraw,私钥支持格式为 pkcs8jwk。因此,您可以以 raw 格式导入公钥,但对于私钥,您必须将其转换为 jwkpkcs8 格式。

您发布的私钥大小为 64 字节,因此由原始 32 字节私钥和原始 32 字节公钥串联而成。

PKCS#8 格式的私钥由前缀 302e020100300506032b657004220420 后跟 32 字节原始私钥组成。

这允许您导入 pkcs8 格式的私钥和 raw 格式的公钥,如下所示:

import { webcrypto } from "node:crypto";

const privateKey = await webcrypto.subtle.importKey(
    "pkcs8",
    Buffer.from("302e020100300506032b65700422042090c2ddd5f636f6d0e35b4ced238962dd525731f089a6ae27d08ffc78b631668b", "hex"),
    {name: "Ed25519"},
    true,
    ["sign"]
);

const publicKey = await webcrypto.subtle.importKey(
    "raw",
    Buffer.from("8669e4b722160bae49020c54e740ba339402299c893538320000b7e7439d956e", "hex"),
    {name: "Ed25519"},
    true,
    ["verify"]
);

const CryptoKeyPair = {
    privateKey,
    publicKey
};
© www.soinside.com 2019 - 2024. All rights reserved.