JS 签名示例
使用 crypto-js 库,支持浏览器和 Node.js 环境。
安装依赖:
npm install crypto-js
import CryptoJS from 'crypto-js';
function signHmacSha256(message, secret) {
return CryptoJS.HmacSHA256(message, secret).toString(CryptoJS.enc.Base64);
}
function buildSignString(method, uri, timestamp, nonce, body) {
return [method, uri, timestamp, nonce, body || '', ''].join('\n');
}
function buildAuthorization(mchid, serial, nonce, timestamp, signature) {
return `KP-CASHIER-HMAC-SHA256 mchid="${mchid}", serial="${serial}", nonce="${nonce}", timestamp="${timestamp}", signature="${signature}"`;
}
function buildClientHeader(sn, name, ip, app, version, session) {
const parts = [
`sn="${sn}"`,
`name="${name}"`,
`ip="${ip}"`,
`app="${app}"`,
`version="${version}"`,
];
if (session) {
parts.push(`session="${session}"`);
}
return parts.join(', ');
}
function generateNonce() {
return CryptoJS.lib.WordArray.random(16).toString();
}
// 示例
const method = 'POST';
const uri = '/open/cashier/trans/micropay';
const timestamp = Math.floor(Date.now() / 1000).toString();
const nonce = generateNonce();
const body = '{"amount":100,"out_trade_no":"TS20260507000001","auth_code":"134567890123456789"}';
const secret = 'your_secret_key';
const signString = buildSignString(method, uri, timestamp, nonce, body);
const signature = signHmacSha256(signString, secret);
const authorization = buildAuthorization('100001', 'KEY001', nonce, timestamp, signature);
const clientHeader = buildClientHeader('SN-DEVICE-001', '收银台A01', '192.168.1.100', 'cashier-pos', '2.0.0', 'abc123');
console.log('Authorization:', authorization);
console.log('Ikudot-Cashier-Client:', clientHeader);
AES 加解密
部分敏感字段(如支付密码)需使用 AES-256-CBC 加密后传输。使用 crypto-js 库实现。
import CryptoJS from 'crypto-js';
function aesEncrypt(plaintext, base64Key) {
const key = CryptoJS.enc.Base64.parse(base64Key);
const iv = CryptoJS.lib.WordArray.random(16);
const encrypted = CryptoJS.AES.encrypt(plaintext, key, {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7,
});
return {
algorithm: 'AES_256_CBC',
ciphertext: encrypted.ciphertext.toString(CryptoJS.enc.Base64),
iv: iv.toString(CryptoJS.enc.Base64),
};
}
function aesDecrypt(base64Ciphertext, base64Iv, base64Key) {
const key = CryptoJS.enc.Base64.parse(base64Key);
const iv = CryptoJS.enc.Base64.parse(base64Iv);
const cipherParams = CryptoJS.lib.CipherParams.create({
ciphertext: CryptoJS.enc.Base64.parse(base64Ciphertext),
});
const decrypted = CryptoJS.AES.decrypt(cipherParams, key, {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7,
});
return decrypted.toString(CryptoJS.enc.Utf8);
}
// 示例
const aesKey = 'Base64EncodedAesKey==';
const plaintext = '123456';
const encrypted = aesEncrypt(plaintext, aesKey);
console.log('加密结果:', encrypted);
const decrypted = aesDecrypt(encrypted.ciphertext, encrypted.iv, aesKey);
console.log('解密结果:', decrypted);