Node.js Signature & Verification Example
In API requests, to ensure data integrity and security, we use the RSA signature mechanism to encrypt and sign requests, and verify signatures on the receiving end.
This example provides a SignatureHandler class for generating signatures and verifying signatures
js
const crypto = require('crypto');
class SignatureHandler {
constructor(key, keyType = 'private') {
/**
* Initialize signature/verification class
* @param {string} key - Private or public key content (without headers and footers)
* @param {string} keyType - Key type, "private" for private key, "public" for public key
*/
if (keyType === 'private') {
// Handle PKCS#8 format private key
this.key = crypto.createPrivateKey({
key: `-----BEGIN PRIVATE KEY-----\n${key.match(/.{1,64}/g).join('\n')}\n-----END PRIVATE KEY-----`,
format: 'pem',
type: 'pkcs8' // Ensure it's 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' // Ensure it's SPKI format
});
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.");
}
// Assemble signature content
const bodyStr = JSON.stringify(body);
const signContent = `${merchantId}.${timestamp}.${timezone}.${bodyStr}`;
// Generate signature
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.");
}
// Assemble signature content
const bodyStr = JSON.stringify(body);
const signContent = `${merchantId}.${timestamp}.${timezone}.${bodyStr}`;
// Verify signature
const verify = crypto.createVerify('SHA256');
verify.update(signContent);
verify.end();
return verify.verify(this.key, receivedSignature, 'base64');
}
}
module.exports = SignatureHandler;