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

如何在Node.js/TypeScript中最简实现JWK转PEM格式

JWK转JWT签名可用PEM格式的最简实现

问题背景

需要从JWK端点下载公钥,将其转换为JWT签名函数所需的PEM格式(对应类型Secret支持的字符串/Buffer形式)。此前尝试通过Web Crypto API的subtle导入JWK得到CryptoKey,再导出为SPKI格式的ArrayBuffer,转Base64后添加PEM信封并换行,但生成的密钥无效。已知该公钥仅支持导出为SPKI和JWK格式。

解决方案

核心问题多为导入密钥时的算法配置不匹配,或是ArrayBuffer转Base64、PEM格式化步骤有误。以下是原生最简实现:

1. 正确导入JWK

导入时需指定与JWT签名算法匹配的参数(以常用的RS256为例,对应算法为RSASSA-PKCS1-v1_5,哈希用SHA-256),同时确保密钥可提取。

2. 导出SPKI格式二进制数据

通过subtle.exportKey导出标准SPKI格式的ArrayBuffer。

3. 转换并格式化PEM

将二进制数据转为Base64字符串,按每64字符分割换行,添加PEM标准头部和尾部。

完整代码示例

import { subtle } from 'crypto'; // Node.js环境导入,浏览器直接用window.crypto.subtle

export type Secret = string | Buffer | { key: string | Buffer; passphrase: string };

async function jwkToPem(webKey: JsonWebKey): Promise<Secret> {
  // 导入JWK,匹配JWT RS256签名算法
  const pubKey = await subtle.importKey(
    'jwk',
    webKey,
    { name: 'RSASSA-PKCS1-v1_5', hash: 'SHA-256' },
    true, // 必须设为true才能导出密钥
    ['verify'] // 公钥用于JWT签名验证
  );

  // 导出为SPKI格式的二进制数据
  const spkiBuffer = await subtle.exportKey('spki', pubKey);

  // 转换为Base64字符串
  const base64 = Buffer.from(spkiBuffer).toString('base64');

  // 格式化PEM:每64字符换行,添加标准头部尾部
  const pemLines = base64.match(/.{1,64}/g) || [];
  return `-----BEGIN PUBLIC KEY-----\n${pemLines.join('\n')}\n-----END PUBLIC KEY-----`;
}

注意事项

  • 若JWT使用其他RSA算法(如RS384、RS512),需对应修改hash参数为SHA-384或SHA-512。
  • Node.js需确保版本在15及以上(原生支持Web Crypto API)。

内容的提问来源于stack exchange,提问作者Milan Baran

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 12:55:11