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

如何在Node.js中使用C#生成的XML格式RSA公钥加密字符串?

在Node.js中使用C#生成的XML格式RSA公钥加密字符串

我来帮你搞定这个需求——Node.js本身不直接支持C#那种XML格式的RSA公钥,所以核心步骤是先把XML密钥转成Node.js crypto模块能识别的PEM格式,再用标准的RSA加密流程处理字符串。下面是具体实现方案:

步骤1:将XML公钥转换为PEM格式

C#生成的XML RSA公钥包含Modulus和Exponent两个核心字段,我们需要把这两个字段提取出来,按照PKCS#1的标准组装成PEM格式的公钥。

写个通用的转换函数:

const crypto = require('crypto');

function xmlRsaPublicKeyToPem(xmlKey) {
  // 从XML中提取Modulus和Exponent
  const modulusMatch = xmlKey.match(/<Modulus>([^<]+)<\/Modulus>/);
  const exponentMatch = xmlKey.match(/<Exponent>([^<]+)<\/Exponent>/);
  
  if (!modulusMatch || !exponentMatch) {
    throw new Error('无效的XML格式RSA公钥');
  }

  // 将base64编码的Modulus和Exponent转为Buffer
  const modulus = Buffer.from(modulusMatch[1], 'base64');
  const exponent = Buffer.from(exponentMatch[1], 'base64');

  // 组装PKCS#1标准的ASN.1结构(RSA公钥的序列格式)
  const totalLength = 6 + modulus.length + exponent.length;
  const buffer = Buffer.alloc(8 + modulus.length + exponent.length);
  
  buffer.writeUInt8(0x30, 0); // ASN.1 SEQUENCE标签
  buffer.writeUInt16BE(totalLength, 1); // 序列总长度
  buffer.writeUInt8(0x02, 3); // INTEGER标签(对应Modulus)
  buffer.writeUInt16BE(modulus.length, 4); // Modulus的长度
  modulus.copy(buffer, 6); // 写入Modulus内容
  buffer.writeUInt8(0x02, 6 + modulus.length); // INTEGER标签(对应Exponent)
  buffer.writeUInt16BE(exponent.length, 7 + modulus.length); // Exponent的长度
  exponent.copy(buffer, 9 + modulus.length); // 写入Exponent内容

  // 转换为PEM格式,按64字符换行
  const pemContent = buffer.toString('base64').match(/.{1,64}/g).join('\n');
  return `-----BEGIN RSA PUBLIC KEY-----\n${pemContent}\n-----END RSA PUBLIC KEY-----`;
}

步骤2:使用PEM公钥加密字符串

拿到PEM格式的公钥后,就可以用crypto.publicEncrypt方法加密字符串了。注意要和C#默认的填充方式保持一致(PKCS#1 v1.5),这样加密后的内容才能被C#正确解密。

加密函数示例:

function encryptWithRsaPublicKey(plainText, pemPublicKey) {
  const encryptedBuffer = crypto.publicEncrypt(
    {
      key: pemPublicKey,
      padding: crypto.constants.RSA_PKCS1_PADDING // 和C#默认的RSA填充方式匹配
    },
    Buffer.from(plainText, 'utf8')
  );
  // 返回base64编码的加密结果
  return encryptedBuffer.toString('base64');
}

完整使用示例

把上面的函数结合起来,测试你的公钥:

// 你的C#生成的XML公钥
const xmlPublicKey = `<RSAKeyValue><Modulus>mlDk9dIwcGJ+sS7kCOiG/xr/1RkM7v7/bUExalwSj7Q/Ul575l4cUGR1ZjC3BtEgmMZjW6xSRTCkgp0WMpdnXGmygV0mQbrAP32NTGoMoWgjTIevBbd+yOMfY8E87bUG0sYUA8+Wk55iEPk3O0Ua5FiLNWIqGTbrF2A5iSp1voc=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>`;

try {
  // 转换XML公钥到PEM
  const pemKey = xmlRsaPublicKeyToPem(xmlPublicKey);
  // 要加密的字符串
  const plainText = '这是需要加密的测试内容';
  // 执行加密
  const encryptedText = encryptWithRsaPublicKey(plainText, pemKey);
  
  console.log('加密结果:', encryptedText);
} catch (error) {
  console.error('加密过程出错:', error.message);
}

重要提示

  • 长文本加密:RSA加密有明文长度限制(一般是密钥长度/8 - 11,比如2048位密钥最多加密245字节),如果要加密长文本,建议使用混合加密:先生成随机AES密钥,用AES加密长文本,再用RSA加密AES密钥,最后把加密后的AES密钥和AES加密文本一起传输。
  • 填充方式一致性:如果你的C#代码使用了OAEP填充(比如RSAEncryptionPadding.OaepSHA1),那么Node.js里需要把padding参数改成crypto.constants.RSA_PKCS1_OAEP_PADDING,同时指定哈希算法,比如:
    {
      key: pemPublicKey,
      padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,
      oaepHash: 'sha1'
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:38:32