给浏览器穿上衣服,防止裸奔

对应普通群体来说,他不知道什么调试断点
对应有点经验的来说,可以看控制台
对应搞网络爬虫的来说,不仅看控制压台,还要抓包,逆向JS

控制台

对应浏览器功鼠标能键来讲,禁用鼠标右键

// 鼠标右键
   document.oncontextmenu = function (event)
    {
      event.returnValue = false; // 阻止浏览器默认事件
      alert('抓贼')
      return false;
    }

打开控制台的组合键有【ctrl+shift+c】【ctrl+shift+j】【ctrl+shift+i】

禁用组合键 ,如按下多个键盘包含 【ctrl】 【shift】【alt】都禁止调,可解决大部分的打开控制台快捷键,当然也阻止了除浏览器自带的其他功能

		// 键盘按下事件
      document.onkeydown = document.onkeyup = document.onkeypress = function (event)
      {
            const { ctrlKey, shiftKey, altKey } = event;
      		ctrlKey || shiftKey || altKey && (event.returnValue = false);
      		return false;
      }

为了用户体验,放出 全选 【ctrl+a】复制【ctrl+c】粘贴【ctrl+v】

// 键盘按下事件
    document.onkeydown = function (event)
    {
      const releaseKey = ['c', 'v', 'a']
      const { ctrlKey, shiftKey, altKey, key } = event
      if (ctrlKey && !releaseKey.includes(key)) {
        ctrlKey || shiftKey || altKey && (event.returnValue = false);
        return false;
      } 

    }

完整代码

禁用F1-F12, 除预设的组合键,其他都禁用

    document.onkeydown = function (event)
    {
      
      const { ctrlKey, shiftKey, altKey, key, keyCode } = event
      // 禁用 F1-F12
      if (FkeyCode.includes(keyCode)) return false;
      // 除组 预定的组合键,其他都禁用
      if (ctrlKey && !releaseKey.includes(key)) {
        console.log(ctrlKey, shiftKey, altKey, ctrlKey || shiftKey || altKey);
        ctrlKey || shiftKey || altKey && (event.returnValue = false);
        return false;
      }
    }

窗口大小

监听当前窗口 如果有变化就关闭当前页面

    let h = window.innerHeight, w = window.innerWidth;
    window.onresize = function ()
    {
      console.log(h, w, window.innerHeight, window.innerWidth)
      if (h !== window.innerHeight || w !== window.innerWidth) {
         window.close();
      //   window.location = "about:blank";
      }
    }

无线断点调试

  (() =>
    {
      const handler = setInterval(() =>
      {
        const before = new Date();
        debugger;
        const after = new Date();
        const cost = after.getTime() - before.getTime();
        if (cost > 100) {
          clearInterval(handler)
        }
      }, 1000)
    })()

窗口大小后在无限debugger

  let h = window.innerHeight, w = window.innerWidth;
    window.onresize = function ()
    {
      console.log(h, w, window.innerHeight, window.innerWidth)
      if (h !== window.innerHeight || w !== window.innerWidth) {
(() =>
    {
      const handler = setInterval(() =>
      {
        const before = new Date();
        debugger;
        const after = new Date();
        const cost = after.getTime() - before.getTime();
        if (cost > 100) {
          clearInterval(handler)
        }
      }, 1000)
    })()
        // window.close();
      //   window.location = "about:blank";
      }
    }

抓包

对于网开发者来说,抓包是我们开发者 无知的,我们不知道什么时候我们的应用程序什么时候被抓包,但是我们可以有对于防止措施

本地存储加密

我们在开发需要登陆的网站或者程序的时候,我们往往会把用户信息存储到浏览器会话里面 【cooki】【localStorage】【IndexDb】【webSql】,这个时候,被不怀好的人拿到用户信息就会造成,用户隐私被泄露

所以在存浏览器会话的重要数据进行加密

之前笔者有 讲解js 的 明文转译 Storage 数据加密解密(转码)存储
然后这个是一个简单实现(浏览器和JavaScriptrunTime)都可用,对于前后端引用,或者其他应用程序是JavaScriptruiunTime 都可以,只是把对于方法提出来即可

对于存储会话数据的加密实现还是建议使用JS 来实现,但是可以用后端求实现,这样会照成不必请求

也可以利用第三库

npm install crypto-js
cnpm install crypto-js
pnpm install crypto-js
yarn add crypto-js

CDM

<script src="https://cdn.bootcdn.net/ajax/libs/crypto-js/4.1.1/aes.js"></script>

Http加密交互

对于现在的网站,都是通过 http 或者是https 进行数据交互,如果不进行加密 一旦被抓包,所有数据都会泄露

对现有网站改造 提供下思路
不管前后端,都在http发送和接受进行加密和解密,这样改造成本是最低的,改造时间也是最少的,动的代码是最少的

前面笔者也有对于文章讲解和实现 加密交换数据 当时也是基于JS 去实现的,同样适用于 JavaScriptruntime
SM(国密)加密

npm install sm-crypto
cnpm install sm-crypto
pnpm install sm-crypto
yarn addcrypto-js
<script src="https://cdn.bootcdn.net/ajax/libs/asmCrypto/2.3.2/asmcrypto.all.es5.js"></script>

国密3 加密封装

const sm3 = require('sm-crypto').sm3
  // 国密加密  的顺序不能修改,否则验证不过!!!
        encryptionSM3(postBody = {}) {
            let obj = { //  定义的加解密规章
                format: 'JSON',
                openid: '7c3c827747ba11fee60747ba1fee6043', //   解密方需要一致
                openkey: 'cd1f8b0b61bb2eed36bdb2eed36bdb78b0b61b2b78b0b6a2', // 解密方需要一致
                postBody,
                signType: 'SM3',
                timestamp: (new Date().getTime(),
            };

            // 字符串拼接
            let str = '';
            for (let key in obj) {
                str += `${key}=${obj[key] instanceof Object ? JSON.stringify(obj[key]) : obj[key]}&`;
            }

            str += `secretKey=cd1f8b0b61bb2eed36bdb2eed36bdb78b0b61b2b78b0b6a2`;

            // 加密后不需要 openkey 带入给后端
            delete obj.openkey;
            let sign = sm3(str).toUpperCase(),
                send = { ...obj,sign};
            return send;
        }

逆向JS

现在的网站主要是JavaScript开发,对于专业扒手来说,找到网站的破解点就是,来反向我们写地JS代码,如实现逻辑,和数据交互加密,都可逆向JS来破解

防护措施
混淆JavaScript代码
缺点,代码体积会膨胀,混淆后开发人员无法识别代码

推荐一个在线
加密后能够正常执行

在vue 或者React 中,通过webpack 打包进行代码混淆配置 vue 项目代码混淆

vite 打包代码混淆配置

npm install rollup-plugin-javascript-obfuscator -D
pnpm install rollup-plugin-javascript-obfuscator -D
yarn add rollup-plugin-javascript-obfuscator --dev
// 混淆js
import obfuscatorPlugin from 'rollup-plugin-javascript-obfuscator'
 // plugins下注入插件配置
 plugins:[
	 {
        ...obfuscatorPlugin({
          options: {
            rotateUnicodeArray: true, // 必须为true
            compact: true, // 紧凑 从输出混淆代码中删除换行符。
            controlFlowFlattening: false, // 此选项极大地影响了运行速度降低1.5倍的性能。 启用代码控制流展平。控制流扁平化是源代码的结构转换,阻碍了程序理解。
            controlFlowFlatteningThreshold: 0.8,
            deadCodeInjection: false, // 此选项大大增加了混淆代码的大小(最多200%) 此功能将随机的死代码块(即:不会执行的代码)添加到混淆输出中,从而使得更难以进行反向工程设计。
            deadCodeInjectionThreshold: 0.5,
            debugProtection: false, // 调试保护  如果您打开开发者工具,可以冻结您的浏览器。 
            debugProtectionInterval: false, // 如果选中,则会在“控制台”选项卡上使用间隔强制调试模式,这使得使用“开发人员工具”的其他功能变得更加困难。它是如何工作的?一个调用调试器的特殊代码;在整个混淆的源代码中反复插入。
            disableConsoleOutput: true, // 通过用空函数替换它们来禁用console.log,console.info,console.error和console.warn。这使得调试器的使用更加困难。
            domainLock: [], // 锁定混淆的源代码,使其仅在特定域和/或子域上运行。这使得有人只需复制并粘贴源代码并在别处运行就变得非常困难。多个域和子域可以将代码锁定到多个域或子域。例如,要锁定它以使代码仅在www.example.com上运行添加www.example.com,以使其在example.com的任何子域上运行,请使用.example.com。
            identifierNamesGenerator: 'hexadecimal', // 标识符的混淆方式 hexadecimal(十六进制) mangled(短标识符)
            identifiersPrefix: '', // 此选项使所有全局标识符都具有特定前缀。
            inputFileName: '',
            log: false,
            renameGlobals: false, // 不要启动 通过声明启用全局变量和函数名称的混淆。 
            reservedNames: [], // 禁用模糊处理和生成标识符,这些标识符与传递的RegExp模式匹配。例如,如果添加^ someName,则混淆器将确保以someName开头的所有变量,函数名和函数参数都不会被破坏。
            reservedStrings: [], // 禁用字符串文字的转换,字符串文字与传递的RegExp模式匹配。例如,如果添加^ some * string,则混淆器将确保以某些字符串开头的所有字符串都不会移动到`stringArray`。
            rotateStringArray: true, // 
            seed: 0, // 默认情况下(seed = 0),每次混淆代码时都会得到一个新结果(即:不同的变量名,插入stringArray的不同变量等)。如果需要可重复的结果,请将种子设置为特定的整数。
            selfDefending: false, // 此选项使输出代码能够抵抗格式化和变量重命名。如果试图在混淆代码上使用JavaScript美化器,代码将不再起作用,使得理解和修改它变得更加困难。需要紧凑代码设置。
            sourceMap: false, // 请确保不要上传嵌入了内嵌源代码的混淆源代码,因为它包含原始源代码。源映射可以帮助您调试混淆的Java Script源代码。如果您希望或需要在生产中进行调试,可以将单独的源映射文件上载到秘密位置,然后将浏览器指向该位置。
            sourceMapBaseUrl: '', // 这会将源的源映射嵌入到混淆代码的结果中。如果您只想在计算机上进行本地调试,则非常有用。
            sourceMapFileName: '',
            sourceMapMode: 'separate',
            stringArray: true, // 将stringArray数组移位固定和随机(在代码混淆时生成)的位置。这使得将删除的字符串的顺序与其原始位置相匹配变得更加困难。如果原始源代码不小,建议使用此选项,因为辅助函数可以引起注意。
            stringArrayEncoding: ["base64"], // 此选项可能会略微降低脚本速度。使用Base64或RC4对stringArray的所有字符串文字进行编码,并插入一个特殊的函数,用于在运行时将其解码回来。
            stringArrayThreshold: 0.8, // 您可以使用此设置调整字符串文字将插入stringArray的概率(从0到1)。此设置在大型代码库中很有用,因为对stringArray函数的重复调用会降低代码的速度。
            target: 'browser', // 您可以将混淆代码的目标环境设置为以下之一: Browser 、Browser No Eval 、Node 目前浏览器和节点的输出是相同的。
            transformObjectKeys: true, // 转换(混淆)对象键。例如,此代码var a = {enabled:true};使用此选项进行模糊处理时,将隐藏已启用的对象键:var a = {};a [_0x2ae0 [('0x0')] = true;。 理想情况下与String Array设置一起使用。
            unicodeEscapeSequence: true, // 将所有字符串转换为其unicode表示形式。例如,字符串“Hello World!”将被转换为“'\ x48 \ x65 \ x6c \ x6c \ x6f \ x20 \ x57 \ x6f \ x72 \ x6c \ x64 \ x21”。
            // ... [See more](https://github.com/javascript-obfuscator/javascript-obfuscator)
          }
        }),
        apply: 'build' // 仅在生产环境下使用
      }
	]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值