拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

前端本地存储数据防篡改:使用 CryptoJS SHA256 签名校验方案

前端本地存储数据防篡改:使用 CryptoJS SHA256 签名校验方案 前言在前端开发中我们经常使用localStorage来临时存储页面间传递的数据比如列表页跳转详情页时把当前行数据存入本地存储。 但是localStorage的数据是明文存储用户打开浏览器开发者工具就可以随意修改里面的 JSON 内容造成页面拿到被篡改后的脏数据引发业务异常。本文提供一套前端数据签名校验方案在存入localStorage时对原始数据 密钥生成 SHA256 签名读取数据的时候使用同样算法重新计算签名进行比对。如果数据被人为修改签名不一致直接判定数据非法。说明本方案仅用于防止普通用户在控制台手动篡改 localStorage 数据不能做到高强度防破解。密钥 secret 写在前端 JS 内有经验的攻击者依然可以提取密钥伪造签名适合页面简单防护场景敏感业务必须后端校验。一、业务场景说明业务场景列表页面点击列表行跳转到详情页。 需求点击列表行排除箭头 img/.arrow 元素把当前行 data 存入 localStorage存入时生成签名data和sign一起打包存储详情页读取本地存储重新计算签名校验如果用户在开发者工具修改了 localStorage 里面 data 字段的任何内容签名校验失败拒绝使用这份数据。点击列表上的箭头图片时不触发跳转详情逻辑。依赖CryptoJS库用于 SHA256 哈希签名。二、完整代码实现列表页存储数据并生成签名跳转详情/** * 跳转详情页存储数据并生成签名 * param {Event} e 点击事件对象 * param {Object} data 需要传递到详情页的行数据 */ function target_detail(e, data) { // 判断点击的是否为箭头img/.arrow元素点击箭头不跳转 if (e.target.closest(img,.arrow)) { // 点击箭头直接return不执行跳转逻辑 return; } const secret my_secret_key_2026; // 签名密钥实际项目可自定义 const store_key user_info; // localStorage存储key // 1、将原始对象转为JSON字符串 const rawStr JSON.stringify(data); // 2、原始数据 密钥做SHA256哈希生成签名sign const sign CryptoJS.SHA256(rawStr secret).toString(); // 3、打包原始数据和签名 const storeVal JSON.stringify({ data, sign }); // 存入本地存储 localStorage.setItem(store_key, storeVal); // 跳转到详情页面 window.location.href ../html/detail.html; }详情页读取本地存储校验签名/** * 读取localStorage数据并校验签名防止数据被篡改 * returns {Object|Boolean} 校验通过返回原始data校验失败/无数据返回false */ function readData() { // 1. 从localStorage取出打包好的字符串 const str localStorage.getItem(user_info); if (!str) { console.log(后台数据为空); return false; } else { // 将字符串解析拆分出存储的数据data和签名sign const { data, sign } JSON.parse(str); const secret my_secret_key_2026; // 密钥必须和列表页保持一致 // 获取数据重新计算签名 const newSign CryptoJS.SHA256(JSON.stringify(data) secret).toString(); // 比对两次签名 if (newSign sign) { // 签名一致数据没有被篡改返回原始数据 return data; } else { // 签名不一致数据被修改过返回false console.log(数据签名校验失败数据已被篡改); return false; } } }页面引入 CryptoJSscript srchttps://cdn.jsdelivr.net/npm/crypto-js4.2.0/crypto-js.min.js/script三、代码分步解析3.1target_detail列表点击跳转函数if (e.target.closest(img,.arrow)) { return; }e.target.closest(img,.arrow)事件委托判断当点击的元素是图片或者.arrow箭头时直接 return不触发跳转详情逻辑。实现「点击列表空白区域跳转点击箭头不跳转」的分离效果。const rawStr JSON.stringify(data); const sign CryptoJS.SHA256(rawStr secret).toString();核心签名逻辑将 JS 对象转为 JSON 字符串原始字符串 密钥secret拼接进行 SHA256 哈希输出十六进制字符串作为签名 sign。只要data里面任意一个字段的值发生改变rawStr就会变化最终生成的sign签名完全不一样。const storeVal JSON.stringify({data, sign}); localStorage.setItem(store_key, storeVal);把data和sign打包成一个对象存入 localStorage。本地存储不再单纯存业务数据而是业务数据 校验签名一起保存。3.2readData详情页校验函数const { data, sign } JSON.parse(str); const newSign CryptoJS.SHA256(JSON.stringify(data) secret).toString(); if (newSign sign) { return data; }else{ return false; }读取流程取出存储字符串JSON 解析得到data和之前生成的sign使用完全相同的密钥和算法基于当前取出的data重新计算一遍签名得到newSign对比newSign和原始sign✅相等数据没有被篡改可以放心使用❌不相等用户在开发者工具修改过 localStorage 内 data数据不可信返回 false页面做拦截提示。四、防篡改原理演示原始存入 localStorage 示例内容{ data: {id:1,name:张三}, sign:4026d1812fxxxxxx }场景用户打开开发者工具手动修改name为李四。 当详情页读取数据JSON.stringify(data)结果发生变化重新计算出来的newSign和原来存储的sign不匹配校验直接失败页面拒绝使用这份篡改后的数据。⚠️注意不是加密是签名data 依然是明文保存在 localStorage用户依然可以看到 data 内容签名只能检测数据是否被改动不能隐藏原始数据。五、方案优缺点分析✅优点实现简单轻量不需要后端参与纯前端完成校验有效阻挡普通用户打开开发者工具随意修改 localStorage 内业务数据搭配前面写的页面禁用 F12、禁用右键代码可以进一步提高篡改门槛SHA256 单向哈希无法通过签名反推出密钥。❌缺点重点secret 密钥写在前端 JS 代码中攻击者可以通过查看源码、断点调试拿到密钥伪造合法签名localStorage 数据依旧明文可见只能防篡改不能隐藏数据只适合页面临时传参这种轻量化场景不能用于登录、权限、敏感核心业务JSON.stringify 序列化存在顺序问题如果对象 key 顺序改变字符串结果会变签名会校验失败可自行做 key 排序优化。六、优化改进方向优化 1对象 key 排序解决 JSON.stringify 顺序问题对象属性顺序不同JSON.stringify生成字符串不一样导致相同数据签名不一致。可以写一个方法把对象 key 排序后再序列化。function sortObjKeys(obj) { return JSON.stringify(obj, Object.keys(obj).sort()); } // 使用 const rawStr sortObjKeys(data);优化 2增加随机盐值每次存储随机 salt每次生成签名时生成随机 saltsalt 和 sign 一起存入 localStorage签名计算改为rawStr salt secret进一步提升伪造难度。优化 3校验失败统一弹窗提示在readData返回 false 时调用之前封装好的showError弹窗提示「数据非法或已被篡改」并跳转回列表页。七、常见误区澄清❌ 使用这个方案数据就安全了 ✅ 只能防篡改校验前端密钥暴露专业人员依旧可以伪造签名前端存储永远不可信。❌ 签名就是加密别人看不到 data 内容 ✅ data 依旧明文存储在 localStorage任何人打开 Application 面板都能查看签名只用来校验是否改动。❌ 可以用来保护用户登录凭证 ✅ 登录态、权限校验这类核心逻辑必须放在后端做签名 / 校验不能依赖前端本地签名。八、配套组合方案这套代码可以和前面三篇博客的代码组合形成一套完整前端页面防护体系页面禁用 F12、禁用右键菜单提高打开开发者工具门槛SHA256 前端密码哈希锁屏页面Fullscreen 全屏切换与状态监听本地存储数据 SHA256 签名防篡改本文整套防护只适合前端演示、内部轻量系统不能作为互联网生产环境安全方案。总结当使用 localStorage 做页面之间数据传递时很容易遇到用户通过开发者工具篡改本地存储数据的问题。我们可以借助 SHA256 哈希签名的思路存储业务数据同时附带签名读取的时候做签名比对检测数据是否被修改。 一定要记住边界前端签名只是增加篡改门槛无法做到绝对安全涉及敏感业务场景所有可信校验逻辑必须放在服务端。
返回列表