js 实现签名
实现数字签名(JavaScript)
使用Web Crypto API实现RSA-PSS签名:
async function generateKeyPair() {
return await window.crypto.subtle.generateKey(
{
name: "RSA-PSS",
modulusLength: 2048,
publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
hash: "SHA-256"
},
true,
["sign", "verify"]
);
}
async function signData(privateKey, data) {
const encoded = new TextEncoder().encode(data);
return await window.crypto.subtle.sign(
{
name: "RSA-PSS",
saltLength: 32
},
privateKey,
encoded
);
}
实现Canvas手写签名
创建基于Canvas的签名板:
const canvas = document.getElementById('signatureCanvas');
const ctx = canvas.getContext('2d');
let isDrawing = false;
canvas.addEventListener('mousedown', startDrawing);
canvas.addEventListener('mousemove', draw);
canvas.addEventListener('mouseup', endDrawing);
canvas.addEventListener('mouseout', endDrawing);
function startDrawing(e) {
isDrawing = true;
ctx.beginPath();
ctx.moveTo(e.offsetX, e.offsetY);
}
function draw(e) {
if (!isDrawing) return;
ctx.lineTo(e.offsetX, e.offsetY);
ctx.stroke();
}
function endDrawing() {
isDrawing = false;
}
function saveSignature() {
const dataURL = canvas.toDataURL('image/png');
localStorage.setItem('signature', dataURL);
}
使用第三方库(signature_pad)
安装签名库:
npm install signature_pad
基本实现:
import SignaturePad from 'signature_pad';
const canvas = document.getElementById('signature-pad');
const signaturePad = new SignaturePad(canvas);
document.getElementById('save').addEventListener('click', () => {
if (signaturePad.isEmpty()) {
alert('请先提供签名');
} else {
const dataURL = signaturePad.toDataURL();
console.log(dataURL);
}
});
document.getElementById('clear').addEventListener('click', () => {
signaturePad.clear();
});
验证数字签名
验证RSA-PSS签名示例:
async function verifySignature(publicKey, signature, data) {
const encoded = new TextEncoder().encode(data);
return await window.crypto.subtle.verify(
{
name: "RSA-PSS",
saltLength: 32
},
publicKey,
signature,
encoded
);
}
签名数据格式化
将ArrayBuffer签名转为Base64:
function arrayBufferToBase64(buffer) {
let binary = '';
const bytes = new Uint8Array(buffer);
for (let i = 0; i < bytes.byteLength; i++) {
binary += String.fromCharCode(bytes[i]);
}
return window.btoa(binary);
}
注意事项
浏览器兼容性检查:
if (!window.crypto || !window.crypto.subtle) {
console.error('Web Crypto API not supported');
}
Canvas签名建议设置样式:
#signatureCanvas {
border: 1px solid #000;
background-color: #f8f8f8;
}
移动端触摸支持需要添加事件监听:
canvas.addEventListener('touchstart', handleTouchStart);
canvas.addEventListener('touchmove', handleTouchMove);






