关于js加密
一、SM3算法简介
SM3是中国国家密码管理局2010年发布的商用密码杂凑算法标准,生成256位固定长度的哈希值,适用于数字签名、消息认证、密码存储等场景。其设计基于Merkle-Damgård结构,安全性等效于国际SHA-256算法,但采用定制化的压缩函数增强抗攻击能力。
二、核心流程
- 消息填充 将输入补足至512位倍数(补1+0...0+64位消息长度)
- 消息扩展 将512位分组扩展为132个32位字
- 迭代压缩 通过64轮压缩函数更新8个寄存器状态
- 结果生成 最终寄存器组合输出256位哈希值4
三、代码演示
C# 实现(需BouncyCastle库)
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..."
引用自1,需安装NuGet包
BouncyCastle.Cryptography
JavaScript 实现(纯前端)
// 精简版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(reg[0](), 12) + reg[4]() + rotateLeft(0x79CC4519, j);
// ...压缩函数逻辑...
}
});
return reg.map(num => num.toString(16)).join('').toUpperCase();
}
// 调用:sm3("123")
引用自2,兼容IE浏览器
四、优缺点分析
| 优势 | 局限 |
|---|---|
| 🔒 安全性强:抗碰撞攻击优于MD5/SHA-13 | 🌐 生态支持弱:非全球通用标准 |
| 🇨🇳 国产合规:满足中国商用密码要求 | ⏱ 性能损耗:比MD5慢约30% |
| 💻 免费开源:无专利限制 | 📚 文档较少:中文资料为主 |
| 📏 固定输出:总为256位,易存储 |
五、SM3 + JsJiami 结合方案
方案1:代码完整性保护
操作步骤:
- 用JsJiami混淆核心代码
- 使用SM3计算混淆后代码的哈希值
- 将哈希值编译进WebAssembly模块
- 前端运行时重新计算哈希并与WASM存储值比对
优势:防止篡改,识别恶意注入
方案2:授权验证系统
// 前端验证伪代码
async function verifyLicense(key) {
const realHash = "A3F5..."; // 后端预计算的SM3哈希
const inputHash = await sm3(key); // 前端SM3计算
if (inputHash === realHash) {
unlockPremiumFeatures(); // 授权通过
} else {
alert("无效授权码");
}
}
流程说明:
- 用户购买后获得授权码
- 后端用SM3哈希授权码并存储
- 前端输入授权码后实时计算SM3对比
- 匹配则激活功能
注意:需配合后端防重放攻击,建议添加时间戳/Salt
结合价值
- 双层防护:Jsjiami防逆向 + SM3防篡改
- 合规性:满足国内密码应用要求
- 轻量化:前端SM3实现仅需10KB