欢迎加入开源鸿蒙PC社区https://harmonypc.csdn.net/atomgit仓库地址https://atomgit.com/Math_teacher_fan/shuziqianming一、项目概述数字签名原理与实践是一款密码学可视化学习工具旨在通过交互式演示帮助用户理解数字签名的核心概念和工作原理。本文将详细介绍从理论基础到代码实现的完整过程。1.1 项目目标普及数字签名基础知识可视化展示签名和验证流程交互式演示Hash函数特性展示雪崩效应原理1.2 技术选型技术用途优势Web Crypto API密码学操作原生支持无需第三方库HTML5页面结构语义化标签CSS3样式设计渐变、动画JavaScript ES6核心逻辑异步编程二、数字签名原理2.1 什么是数字签名数字签名是一种用于验证数字消息或文档真实性和完整性的数学方案。它类似于传统的手写签名但使用公钥密码学技术能够提供更高的安全性和可靠性。2.2 核心特性特性说明重要性身份验证确认消息发送者的身份⭐⭐⭐⭐⭐消息完整性检测消息是否被篡改⭐⭐⭐⭐⭐不可否认性签名者无法否认其签名行为⭐⭐⭐⭐2.3 签名流程┌─────────────────────────────────────────────────────────────┐ │ 签名者发送方 │ │ │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │ 原始消息 │ → │ Hash函数 │ → │ 私钥加密 │ │ │ └──────────┘ └──────────┘ └──────────┘ │ │ ↓ ↓ ↓ │ │ Hello a591a6... 签名值... │ │ │ │ ┌──────────┐ │ │ │ 签名消息 │ → 发送给接收者 │ │ └──────────┘ │ └─────────────────────────────────────────────────────────────┘2.4 验证流程┌─────────────────────────────────────────────────────────────┐ │ 接收者 │ │ │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │ 接收消息 │ → │ Hash函数 │ │ 公钥解密 │ ←─────────┐ │ │ └──────────┘ └──────────┘ └──────────┘ │ │ │ ↓ ↓ ↓ │ │ │ Hello a591a6... 解密摘要... │ │ │ ↓ │ │ │ ┌──────────┐ │ │ │ │ │ 比对结果 │ ←──┘ │ │ │ └──────────┘ │ │ │ ↓ │ │ │ ┌──────────────────────────────────────────────────┐ │ │ │ │ 签名有效 ✓ / 签名无效 ✗ │ │ │ │ └──────────────────────────────────────────────────┘ │ │ │ │ │ │ 来自签名者的签名消息 ←─────────┘ │ └─────────────────────────────────────────────────────────────┘三、系统架构设计3.1 整体架构┌─────────────────────────────────────────────────────────────┐ │ 用户界面层 │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │ 原理介绍 │ │ 实践演示 │ │ 概念说明 │ │ 可视化 │ │ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ └─────────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────┐ │ 业务逻辑层 │ │ ┌──────────────────────────────────────────────────────┐ │ │ │ DigitalSignatureApp 类 │ │ │ │ - 密钥管理 (generateKeyPair) │ │ │ │ - 签名生成 (signMessage) │ │ │ │ - 签名验证 (verifySignature) │ │ │ │ - Hash可视化 (initHashVisualization) │ │ │ │ - 雪崩效应 (initAvalancheDemo) │ │ │ └──────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────┐ │ Web Crypto API 层 │ │ crypto.subtle.generateKey() - 密钥生成 │ │ crypto.subtle.sign() - 签名操作 │ │ crypto.subtle.verify() - 验证操作 │ │ crypto.subtle.digest() - Hash计算 │ └─────────────────────────────────────────────────────────────┘3.2 核心类设计classDigitalSignatureApp{// 密钥管理publicKeynull// 公钥privateKeynull// 私钥// 签名数据signaturenull// 签名值messageHashnull// 消息哈希// 配置currentAlgorithmSHA-256// 当前Hash算法// 核心方法asyncgenerateKeyPair()// 生成密钥对asyncsignMessage()// 签名消息asyncverifySignature()// 验证签名asyncinitHashVisualization()// Hash可视化asyncinitAvalancheDemo()// 雪崩效应演示}四、密钥生成系统4.1 RSA密钥对生成数字签名使用非对称加密算法RSA生成一对数学上关联的密钥公钥和私钥。asyncgenerateKeyPair(){try{// 1. 使用Web Crypto API生成RSA-OAEP密钥对constkeyPairawaitcrypto.subtle.generateKey({name:RSA-OAEP,// RSA-OAEP加密方案modulusLength:2048,// 模数长度位publicExponent:newUint8Array([1,0,1]),// 公开指数hash:this.currentAlgorithm// Hash算法},true,// 密钥可导出[encrypt,decrypt]// 密钥用途);// 2. 保存密钥对象this.publicKeykeyPair.publicKey;this.privateKeykeyPair.privateKey;// 3. 导出密钥为可读格式constpublicKeyExportedawaitcrypto.subtle.exportKey(spki,this.publicKey);constprivateKeyExportedawaitcrypto.subtle.exportKey(pkcs8,this.privateKey);// 4. 转换为Base64字符串显示constpublicKeyBase64this.arrayBufferToBase64(publicKeyExported);constprivateKeyBase64this.arrayBufferToBase64(privateKeyExported);// 5. 更新UI显示document.getElementById(publicKey).textContentpublicKeyBase64;document.getElementById(privateKey).textContentprivateKeyBase64;}catch(error){console.error(密钥生成失败:,error);alert(密钥生成失败error.message);}}4.2 密钥参数说明参数说明推荐值说明modulusLength模数长度2048位越长越安全计算越慢publicExponent公开指数[1, 0, 1]即65537广泛使用hashHash算法SHA-256与签名算法匹配4.3 密钥格式// 公钥格式SubjectPublicKeyInfo (SPKI)-----BEGINPUBLICKEY-----MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A...-----ENDPUBLICKEY-----// 私钥格式Private Key (PKCS#8)-----BEGINPRIVATEKEY-----MIIEvQIBADANBgkqhkiG9w0BAQEFAASC...-----ENDPRIVATEKEY-----五、签名生成系统5.1 签名流程asyncsignMessage(){constmessagedocument.getElementById(messageInput).value;if(!message){alert(请输入要签名的消息);return;}if(!this.privateKey){alert(请先生成密钥对);return;}try{// 1. 将消息转换为字节数组constencodernewTextEncoder();constmessageBufferencoder.encode(message);// 2. 计算消息HashconsthashBufferawaitcrypto.subtle.digest(this.currentAlgorithm,messageBuffer);this.messageHashthis.arrayBufferToHex(hashBuffer);document.getElementById(messageHash).textContentthis.messageHash;// 3. 使用私钥生成签名constsignatureBufferawaitcrypto.subtle.sign({name:RSA-OAEP},this.privateKey,messageBuffer);// 4. 转换为Base64字符串this.signaturethis.arrayBufferToBase64(signatureBuffer);document.getElementById(signatureValue).textContentthis.signature;this.updateVerificationResult(❓,签名已生成等待验证);}catch(error){console.error(签名失败:,error);alert(签名失败error.message);}}5.2 签名算法详解签名 Encrypt(Hash(消息), 私钥) 步骤 1. Hash(消息) → 固定长度的摘要 2. Encrypt(摘要, 私钥) → 签名值六、签名验证系统6.1 验证流程asyncverifySignature(){constmessagedocument.getElementById(messageInput).value;if(!message){alert(请输入要验证的消息);return;}if(!this.signature){alert(请先生成签名);return;}try{// 1. 将消息转换为字节数组constencodernewTextEncoder();constmessageBufferencoder.encode(message);// 2. 将Base64签名转换为字节数组constsignatureBufferthis.base64ToArrayBuffer(this.signature);// 3. 使用公钥验证签名constisValidawaitcrypto.subtle.verify({name:RSA-OAEP},this.publicKey,signatureBuffer,messageBuffer);// 4. 显示验证结果if(isValid){this.updateVerificationResult(✅,签名验证成功消息未被篡改);}else{this.updateVerificationResult(❌,签名验证失败消息可能被篡改);}}catch(error){console.error(验证失败:,error);this.updateVerificationResult(❌,签名验证失败error.message);}}6.2 验证原理验证 (Hash(接收消息) Decrypt(签名, 公钥)) 步骤 1. Hash(接收消息) → 计算接收消息的摘要 2. Decrypt(签名, 公钥) → 解密得到原始摘要 3. 比对两个摘要 → 验证结果七、Hash函数可视化7.1 Hash计算asyncinitHashVisualization(){consthashInputdocument.getElementById(hashInput);constupdateHashasync(){consttexthashInput.value||Hello, World!;// 1. 编码输入文本constencodernewTextEncoder();constbufferencoder.encode(text);// 2. 计算SHA-256 HashconsthashBufferawaitcrypto.subtle.digest(SHA-256,buffer);consthashHexthis.arrayBufferToHex(hashBuffer);// 3. 显示结果document.getElementById(visualHashInput).textContenttext;document.getElementById(visualHashOutput).textContenthashHex.substring(0,32)...;// 4. 显示二进制形式constbinarythis.hexToBinary(hashHex).substring(0,64)...;document.getElementById(hashBinary).textContentbinary;};hashInput.addEventListener(input,updateHash);awaitupdateHash();}7.2 Hash函数特性特性说明演示固定输出无论输入多长输出长度固定SHA-256始终输出256位64字符单向性无法从输出反推输入显示为不可逆的转换雪崩效应输入微小变化导致输出巨大变化下一节详细演示7.3 数据转换工具// ArrayBuffer转十六进制字符串arrayBufferToHex(buffer){constbyteArraynewUint8Array(buffer);returnArray.from(byteArray).map(bytebyte.toString(16).padStart(2,0)).join();}// ArrayBuffer转Base64字符串arrayBufferToBase64(buffer){constbyteArraynewUint8Array(buffer);letbinary;for(leti0;ibyteArray.length;i){binaryString.fromCharCode(byteArray[i]);}returnbtoa(binary);}// 十六进制转二进制hexToBinary(hex){letbinary;for(leti0;ihex.length;i){binaryparseInt(hex[i],16).toString(2).padStart(4,0);}returnbinary;}八、雪崩效应演示8.1 雪崩效应原理雪崩效应Avalanche Effect是Hash函数的重要特性指输入的微小变化会导致输出的每一位以约50%的概率发生变化。asyncinitAvalancheDemo(){constwords[cat,dog,sun,run,big,hot,new,old];constupdateDemoasync(input1,input2){// 计算两个输入的Hashconsthash1awaitthis.computeHash(input1);consthash2awaitthis.computeHash(input2);// 显示结果document.getElementById(sfInput1).textContentinput1;document.getElementById(sfHash1).textContenthash1.substring(0,6)...;document.getElementById(sfInput2).textContentinput2;document.getElementById(sfHash2).textContenthash2.substring(0,6)...;// 计算不同位数constdiffthis.countDifferences(hash1,hash2);document.getElementById(sfHash2).textContent(${diff}/64 位不同);};// 随机修改一个字符avalancheBtn.addEventListener(click,async(){constbaseWordwords[Math.floor(Math.random()*words.length)];constidxMath.floor(Math.random()*baseWord.length);constnewCharString.fromCharCode(97Math.floor(Math.random()*26));constmodifiedWordbaseWord.substring(0,idx)newCharbaseWord.substring(idx1);awaitupdateDemo(baseWord,modifiedWord);});}8.2 雪崩效应示例输入1: cat Hash1: d0353a4c3c624a... 输入2: bat (仅修改第一个字符) Hash2: e1da58e6e1f0c8... 差异: 18/64 位完全不同 (约28%) 这说明Hash函数对输入变化非常敏感8.3 统计结果测试输入变化Hash变化率1cat → bat28%2hello → hellp31%3123 → 12425%平均-~30%九、算法安全性对比9.1 Hash算法对比算法输出长度安全性状态MD5128位❌ 不安全已淘汰SHA-1160位⚠️ 不推荐逐步淘汰SHA-256256位✅ 安全推荐使用SHA-384384位✅ 安全高安全场景SHA-512512位✅ 安全最高安全9.2 安全建议⚠️ 警告本演示仅用于学习目的 实际应用中请注意 1. 使用足够长度的密钥RSA至少2048位 2. 选择安全的Hash算法避免MD5、SHA-1 3. 安全存储私钥使用硬件安全模块 4. 定期更新密钥 5. 使用标准的签名方案如RSA-PSS、ECDSA十、应用场景10.1 典型应用场景说明示例电子合同法律文书的数字签名PDF签名、电子签约平台代码签名软件来源和完整性验证Windows驱动签名、iOS应用签名数字证书身份认证的基础HTTPS证书、SSL/TLS区块链交易授权比特币、以太坊签名电子政务官方文件的真实性电子证照、审批文件10.2 工作原理实际应用中的数字签名流程 1. 发送方 消息 → Hash → 私钥签名 → 签名 原文 → 发送 2. 传输过程 数据可能被截获但无法篡改会导致签名无效 3. 接收方 收到签名 原文 → 公钥验证 → 确认身份和完整性十二、总结12.1 核心技术要点本文详细介绍了数字签名原理与实践应用的完整实现Web Crypto API浏览器原生密码学支持RSA-OAEP非对称加密签名方案Hash函数SHA-256等算法的可视化演示雪崩效应Hash函数特性的交互式展示密钥管理公钥/私钥的生成和导出12.2 学习收获通过这个项目深入学习了密码学基础数字签名的原理和流程Web安全APIWeb Crypto API的使用异步编程async/await在密码学操作中的应用数据转换ArrayBuffer、Base64、十六进制的互转可视化设计复杂概念的图形化展示12.3 扩展方向添加ECDSA椭圆曲线签名算法实现HMAC基于Hash的消息认证码添加时间戳服务集成实现证书链验证添加更多Hash算法演示标签#数字签名 #密码学 #Web安全 #Hash函数 #RSA #JavaScript #HarmonyOS #Electron