electron 代码 加密

常见前端代码加密方式

​ 如果“加密”就是让别人无法反向工程摸索你的代码逻辑的话,那是没办法的,其实任何一种语言都避免不了被反向工程,而JavaScript的特点是下载到了客户的机器上执行,所以无论如何都可以被摸清楚,只是困难度而已!那我们怎么增加困难度呢?

常见的一些nodejs “加密的办法”

  • 代码压缩
  • 代码混淆
  • JS 自己加载 加密的文件和执行内容(解密方法暴露了)
  • 代码内容存入一些特殊的文件内(例如png等),然后加载
  • 利用 enclosejs (是一款开源的打包、加密工具;用于打包、加密nodejs的的工程)
  • ….

electron 中的前端代码

​ electron的 代码是直接随安装包一起发布的,上述的一些方法完全起不到任何作用,electron又不像 nw、cef那样提供一些丰富的接口可以达到加密的目的,官方只有一个 asar 压缩代码,那怎么解决呢?

加密的目的:

  • 源码加密
  • 解密方式不好破解

纯前端方式无法实现,那么借助C++来实现,如何实现:

  • C++ 调用读取加密文件
  • C++ 解密文件
  • C++ 加载运行JavaScript

这样就可以比较完整的解决加密的问题,C++ 不知道加密文件地址,那么把加密文件路径传递给C++解密去运行

代码加密实现

需要实现的内容:

  • 遍历获取所有的 JS 代码文件
  • AES 加密文件内容存放到一个地址
  • 源文件内容修改为 加载C++加密模块 传入加密之后的路径

获取所有 JS 代码路径

//遍历 递归 获取js文件列表
function GetJsFiles(pathDir) {
    var files = fs.readdirSync(pathDir)
    files.forEach(function(filename) {
        var filepath = path.join(pathDir, filename)
        var info = fs.statSync(filepath)
        if (info.isFile() && path.extname(filepath) == ".js") {
            // console.log(filepath)
            jsFileList.push(filepath)
        }
        if (info.isDirectory()) {
            GetJsFiles(filepath)
        }
    })
}

文件内容AES 加密

const crypto = require('crypto')
const fs = require('fs')
const path = require('path')
const md5file = require('md5-file')

//输入 utf8 输出 binary 加密
var encryptData = function(chCodeId, filedata) { //传入文件的MD5值 作为key 和向量的 参数

    var _iv = new Buffer(chCodeId.slice(4, 20)) //从md5值 的第5位开始取16个值
    var _ucKey = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
    var _Key = new Buffer(_ucKey)

    console.log(_iv.toString())
    var cipher = crypto.createCipheriv(algorithm, _Key, _iv)
    var crypted = cipher.update(filedata, 'utf8', 'binary')
    crypted += cipher.final('binary')
    return crypted
}

修改原JS代码文件的内容

function modifyJsfile(filepath, md5value,isEnode) {
  var stringcode = `
  const path = require('path');
  const resourcesDirPath = (process.resourcesPath = process.resourcesPath || process.env.resourcesPath);
  var yzj_loadjs = require('decrypt');
  yzj_loadjs.Load(${isEnode},resourcesDirPath, '${md5value}' , null, require, null, __filename, __dirname, process);
  yzj_loadjs = null;
  `
  fs.writeFileSync(filepath, stringcode.trim(), 'utf8')
}

通过 process.resourcesPath = process.resourcesPath || process.env.resourcesPath 获取electron下资源文件夹目录

require(‘decrypt’) 为解密模块

传入的参数:

  • isEnode 是否加密了
  • resourcesDirPath 资源文件目录
  • md5value 源文件加密之后的md5值 用来找到源文件

其他参数有什么用,后面解密部分你就会了解

加密JS文件列表 并且写入 指定目录中

function EncodeJSfiles(fileList, encodeJSfilePath,isEnode) {
    fileList.forEach(function(filename) {
        //获取原文件的md5值
        md5file(filename, function(err, hash) {
            if (err) throw err
            var filedata = fs.readFileSync(filename, 'utf8')
            console.log('读取文件内容文件:' + filename)
            if (!fs.existsSync(encodeJSfilePath)) {
                fs.mkdirSync(encodeJSfilePath)
            }
            var savefilename = path.join(encodeJSfilePath, hash)
            console.log('对文件内容进行加密处理:' + filename)
            if (isEnode == true) {
                var enfileData = encryptData(hash, filedata)
                console.log('对加密的内容存入文件:' + savefilename)
                fs.writeFileSync(savefilename, enfileData, { 'encoding': 'binary' }) //把加密后的内容写入文件
            } else {
                console.log('对未加密的内容存入文件:' + savefilename)
                fs.writeFileSync(savefilename, filedata, { 'encoding': 'utf8' }) //把加密后的内容写入文件
            }
            console.log('对原js代码文件内容进行更改:' + filename)
            modifyJsfile(filename,hash,isEnode)
        })
    })
}

总结

代码加密部分比较容易实现,主要是解密,解密请参考下一篇文章



所有图片均来自网络


   转载规则


《electron 代码 加密》 Smoking 采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。
 上一篇
electron 代码 解密 electron 代码 解密
解密模块需要解决的问题 在读取指定路径的加密文件 AES 解密代码文件 加载 JS 解密之后的内容 怎么加载nodejs模块加载机制 require() 源码解读 通过了解nodejs 的模块加载机制 其实执行的主要代码类似 (funct
2019-05-24
下一篇 
electron编译文件清理 electron编译文件清理
windows 平台清理垃圾文件对执行程序无用的垃圾文件有那些 C++工程编译的文件 mac 端才使用的模块文件 文档文件 例如 markdown、doc、excel 等这类开发文档文件 C++ 源代码文件,如 cpp、cc、h、hpp 等
2019-05-24
  目录