SM3加密算法详解与应用方案

关于js加密

WX20231204-144436@2x.png

一、SM3算法简介

SM3是中国国家密码管理局2010年发布的商用密码杂凑算法标准,生成256位固定长度的哈希值,适用于数字签名、消息认证、密码存储等场景。其设计基于Merkle-Damgård结构,安全性等效于国际SHA-256算法,但采用定制化的压缩函数增强抗攻击能力。

2025年09月23日.1.png

二、核心流程

  1. 消息填充 将输入补足至512位倍数(补1+0...0+64位消息长度)

  2. 消息扩展 将512位分组扩展为132个32位字

  3. 迭代压缩 通过64轮压缩函数更新8个寄存器状态

  4. 结果生成 最终寄存器组合输出256位哈希值4

三、代码演示

C# 实现(需BouncyCastle库)

<pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" lang="c#" cid="n197" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; caret-color: rgb(0, 122, 255); color: rgb(51, 51, 51); font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-indent: 0px; text-transform: none; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;">using Org.BouncyCastle.Crypto.Digests;
using Org.BouncyCastle.Utilities.Encoders;

public string SM3Encrypt(string input)
{
byte[] msg = Encoding.UTF8.GetBytes(input);
byte[] md = new byte[32]; // 256位输出

SM3Digest sm3 = new SM3Digest();
sm3.BlockUpdate(msg, 0, msg.Length);
sm3.DoFinal(md, 0);

return Hex.ToHexString(md).ToUpper(); // 返回十六进制字符串
}
// 示例:SM3Encrypt("123") → "66C7F0F462EEEDD9D1E2DDBE0F4..."</pre>

引用自1,需安装NuGet包 BouncyCastle.Cryptography

JavaScript 实现(纯前端)

<pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" lang="js" cid="n201" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; caret-color: rgb(0, 122, 255); color: rgb(51, 51, 51); font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-indent: 0px; text-transform: none; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;">// 精简版SM3实现(完整代码见引用)
function sm3(input) {
// 初始化寄存器
let reg = [0x7380166f, 0x4914b2b9, ...];

// 消息填充与分组
let chunks = padMessage(input);

// 迭代压缩
chunks.forEach(chunk => {
for (let j = 0; j < 64; j++) {
const SS1 = rotateLeft(reg0, 12) + reg4 + rotateLeft(0x79CC4519, j);
// ...压缩函数逻辑...
}
});

return reg.map(num => num.toString(16)).join('').toUpperCase();
}
// 调用:sm3("123")</pre>

引用自2,兼容IE浏览器

四、优缺点分析

优势 局限
🔒 安全性强:抗碰撞攻击优于MD5/SHA-13 🌐 生态支持弱:非全球通用标准
🇨🇳 国产合规:满足中国商用密码要求 ⏱ 性能损耗:比MD5慢约30%
💻 免费开源:无专利限制 📚 文档较少:中文资料为主
📏 固定输出:总为256位,易存储

五、SM3 + JsJiami 结合方案

方案1:代码完整性保护

操作步骤

  1. 用JsJiami混淆核心代码

  2. 使用SM3计算混淆后代码的哈希值

  3. 将哈希值编译进WebAssembly模块

  4. 前端运行时重新计算哈希并与WASM存储值比对

优势:防止篡改,识别恶意注入

方案2:授权验证系统

<pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" lang="js" cid="n236" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; caret-color: rgb(0, 122, 255); color: rgb(51, 51, 51); font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-indent: 0px; text-transform: none; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;">// 前端验证伪代码
async function verifyLicense(key) {
const realHash = "A3F5..."; // 后端预计算的SM3哈希
const inputHash = await sm3(key); // 前端SM3计算

if (inputHash === realHash) {
unlockPremiumFeatures(); // 授权通过
} else {
alert("无效授权码");
}
}</pre>

流程说明

  1. 用户购买后获得授权码

  2. 后端用SM3哈希授权码并存储

  3. 前端输入授权码后实时计算SM3对比

  4. 匹配则激活功能

注意:需配合后端防重放攻击,建议添加时间戳/Salt

结合价值

  1. 双层防护:Jsjiami防逆向 + SM3防篡改

  2. 合规性:满足国内密码应用要求

  3. 轻量化:前端SM3实现仅需10KB

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容