Skip to content
node-forge实现RSA2(SHA256WithRSA)签名算法

安装node-forge

首先需要安装node-forge:

bash
npm install node-forge

实现代码

以下是完整的实现代码:

javascript
const forge = require('node-forge');

/**
 * 生成RSA密钥对
 * @param {number} [keySize=2048] - 密钥大小,默认2048位
 * @returns {Object} 包含公钥和私钥的对象
 */
function generateKeyPair(keySize = 2048) {
  const keyPair = forge.pki.rsa.generateKeyPair({ bits: keySize, e: 0x10001 });
  return {
    privateKey: forge.pki.privateKeyToPem(keyPair.privateKey),
    publicKey: forge.pki.publicKeyToPem(keyPair.publicKey)
  };
}

/**
 * RSA2签名(SHA256WithRSA)
 * @param {string} data - 要签名的数据
 * @param {string} privateKey - PEM格式的私钥
 * @returns {string} Base64编码的签名
 */
function rsa2Sign(data, privateKey) {
  // 将PEM格式私钥转换为forge私钥对象
  const privateKeyObj = forge.pki.privateKeyFromPem(privateKey);

  // 创建SHA256摘要
  const md = forge.md.sha256.create();
  md.update(data, 'utf8');

  // 使用私钥签名
  const signature = privateKeyObj.sign(md);

  // 返回Base64编码的签名
  return forge.util.encode64(signature);
}

/**
 * 验证RSA2签名
 * @param {string} data - 原始数据
 * @param {string} signature - Base64编码的签名
 * @param {string} publicKey - PEM格式的公钥
 * @returns {boolean} 签名是否有效
 */
function rsa2Verify(data, signature, publicKey) {
  // 将PEM格式公钥转换为forge公钥对象
  const publicKeyObj = forge.pki.publicKeyFromPem(publicKey);

  // 创建SHA256摘要
  const md = forge.md.sha256.create();
  md.update(data, 'utf8');

  // 解码Base64签名
  const signatureBytes = forge.util.decode64(signature);

  // 验证签名
  return publicKeyObj.verify(md.digest().bytes(), signatureBytes);
}

// 示例用法
(async () => {
  try {
    // 1. 生成密钥对
    const { privateKey, publicKey } = generateKeyPair();
    console.log('私钥:', privateKey);
    console.log('公钥:', publicKey);

    // 2. 要签名的数据
    const data = '这是要签名的数据';

    // 3. 生成签名
    const signature = rsa2Sign(data, privateKey);
    console.log('签名:', signature);

    // 4. 验证签名
    const isValid = rsa2Verify(data, signature, publicKey);
    console.log('签名验证结果:', isValid ? '有效' : '无效');

    // 测试篡改数据后的验证
    const tamperedData = '这是被篡改的数据';
    const isTamperedValid = rsa2Verify(tamperedData, signature, publicKey);
    console.log('篡改后验证结果:', isTamperedValid ? '有效' : '无效');
  } catch (err) {
    console.error('发生错误:', err);
  }
})();

代码说明

  1. generateKeyPair() - 生成RSA密钥对,默认2048位,返回PEM格式的公私钥

  2. rsa2Sign() - RSA2签名函数,使用SHA256WithRSA算法:

    • 将PEM私钥转换为forge私钥对象
    • 创建SHA256摘要
    • 使用私钥签名
    • 返回Base64编码的签名
  3. rsa2Verify() - RSA2签名验证函数:

    • 将PEM公钥转换为forge公钥对象
    • 创建SHA256摘要
    • 解码Base64签名
    • 验证签名是否有效

注意事项

  1. 实际应用中,私钥需要妥善保管,不要硬编码在代码中或提交到版本控制系统
  2. 对于大量数据签名,建议先对数据进行哈希,再对哈希值签名
  3. 密钥长度建议至少2048位,安全性要求高的场景可以使用4096位
  4. 如果需要与其他系统(如Java、PHP等)交互签名,需要确保双方使用相同的编码格式和填充方案

Updated at: