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

NodeJS中使用证书公钥调用Crypto.publicEncrypt()报错求助

Node.js v16/v17中使用证书公钥调用crypto.publicEncrypt()报错的解决方法

问题场景

使用Node.js v16/v17版本,尝试通过PEM格式的证书公钥调用crypto.publicEncrypt()加密数据,两段测试代码均报错:

  • 测试代码1:
const pkey = '-----BEGIN CERTIFICATE-----\n    <Encoding>\n    -----END CERTIFICATE-----'
const pubPemKey = crypto.createPublicKey(pkey)
const pubPemKeyStr = pubPemKey.export({ type: 'spki', format: 'pem' })
console.log(pubPemKeyStr)
const encryptedData = crypto.publicEncrypt(pubPemKeyStr, Buffer.from('test'))
  • 测试代码2:
const encryptedKey = crypto.publicEncrypt({
  key: pkey,
  padding: crypto.constants.RSA_PKCS1_PADDING
}, Buffer.from(plainText))

报错信息:

node:internal/crypto/cipher:79
return method(data, format, type, passphrase, buffer, padding, oaepHash,
       ^
Error: error:0608B096:digital envelope routines:EVP_PKEY_encrypt_init:operation not supported for this keytype
    at Object.publicEncrypt (node:internal/crypto/cipher:79:12)
    at Object.<anonymous> (/home/jdoodle.js:28:30)
    at Module._compile (node:internal/modules/cjs/loader:1097:14)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1149:10)
    at Module.load (node:internal/modules/cjs/loader:975:32)
    at Function.Module._load (node:internal/modules/cjs/loader:822:12)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)
    at node:internal/main/run_main_module:17:47 {
  library: 'digital envelope routines',
  function: 'EVP_PKEY_encrypt_init',
  reason: 'operation not supported for this keytype',
  code: 'ERR_OSSL_EVP_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE'
}

解决方法

核心原因

PEM格式的证书并非直接可用于加密的公钥,它包含公钥、身份信息及签名等额外数据。直接传入证书会导致Node.js无法识别正确的加密密钥类型,因此触发报错。

步骤与修正代码

  1. 从证书中提取出可用于加密的纯公钥
  2. 使用提取后的公钥执行加密操作

修正后的示例代码:

const crypto = require('crypto');

// 替换为你的实际证书PEM内容
const certPem = `-----BEGIN CERTIFICATE-----
<你的证书编码内容>
-----END CERTIFICATE-----`;

// 从证书创建KeyObject
const certKey = crypto.createPublicKey(certPem);

// 导出SPKI格式的纯公钥(可直接用于加密)
const publicKey = certKey.export({ type: 'spki', format: 'pem' });

// 执行加密,根据需求指定合适的padding规则
const encryptedData = crypto.publicEncrypt(
  {
    key: publicKey,
    padding: crypto.constants.RSA_PKCS1_PADDING
  },
  Buffer.from('test')
);

// 输出加密后的base64格式内容
console.log(encryptedData.toString('base64'));

额外注意事项

  • 确认证书公钥算法支持加密:可以通过certKey.asymmetricKeyType查看密钥类型,rsa类型默认支持加密;若为ec(椭圆曲线)类型,需确保使用的EC算法支持加密操作(部分EC密钥仅用于签名)。
  • 若直接使用KeyObject加密,需确保该对象对应的是提取后的纯公钥而非原始证书容器,避免再次触发类型不兼容报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 09:15:55