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

node-forge是一个纯JavaScript实现的加密工具库,可以用来实现RSA签名算法。下面我将展示如何使用node-forge实现RSA2(即SHA256WithRSA)签名算法。

安装node-forge

首先需要安装node-forge:

1
npm install node-forge

实现代码

以下是完整的实现代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
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等)交互签名,需要确保双方使用相同的编码格式和填充方案