切换主题
Node 签名 & 验签 示例
在 API 请求中,为了确保数据的完整性和安全性,我们使用 RSA 签名 机制来对请求进行加密签名,并在接收方进行验签。
本示例提供了一个 SignatureHandler 类,用于 生成签名 和 验证签名
js
const crypto = require('crypto');
class SignatureHandler {
constructor(key, keyType = 'private') {
/**
* 初始化签名/验签类
* @param {string} key - 私钥或公钥内容(无头尾)
* @param {string} keyType - 键类型,"private" 表示私钥,"public" 表示公钥
*/
if (keyType === 'private') {
// 处理 PKCS#8 格式的私钥
this.key = crypto.createPrivateKey({
key: `-----BEGIN PRIVATE KEY-----\n${key.match(/.{1,64}/g).join('\n')}\n-----END PRIVATE KEY-----`,
format: 'pem',
type: 'pkcs8' // 确保是 PKCS#8
});
this.isPrivate = true;
} else if (keyType === 'public') {
this.key = crypto.createPublicKey({
key: `-----BEGIN PUBLIC KEY-----\n${key.match(/.{1,64}/g).join('\n')}\n-----END PUBLIC KEY-----`,
format: 'pem',
type: 'spki' // 确保是 SPKI 格式
});
this.isPrivate = false;
} else {
throw new Error("Invalid keyType. Must be 'private' or 'public'.");
}
}
generateSignature(merchantId, timestamp, timezone, body) {
if (!this.isPrivate) {
throw new Error("Key must be private to generate signature.");
}
// 拼接签名内容
const bodyStr = JSON.stringify(body);
const signContent = `${merchantId}.${timestamp}.${timezone}.${bodyStr}`;
// 生成签名
const sign = crypto.createSign('SHA256');
sign.update(signContent);
sign.end();
const signature = sign.sign(this.key, 'base64');
return signature;
}
verifySignature(merchantId, timestamp, timezone, body, receivedSignature) {
if (this.isPrivate) {
throw new Error("Key must be public to verify signature.");
}
// 拼接签名内容
const bodyStr = JSON.stringify(body);
const signContent = `${merchantId}.${timestamp}.${timezone}.${bodyStr}`;
// 验证签名
const verify = crypto.createVerify('SHA256');
verify.update(signContent);
verify.end();
return verify.verify(this.key, receivedSignature, 'base64');
}
}
module.exports = SignatureHandler;