Сначала я был сбит с толку, когда услышал это требование: в качестве программного обеспечения для чата в коде нет так называемых основных алгоритмов и бизнес-секретов, так зачем вам защищать исходный код. Более того, сам Электрон предоставляет при упаковке
asar
Этот формат файла архива инкапсулирует весь исходный код и зависимости.
нужно
После некоторого анализа защита исходного кода проекта Electron все еще необходима.
-
asarЭто всего лишь объединенный архив исходного кода, в котором не предусмотрены такие операции, как шифрование.
пройти через
asar e
команду, вы можете легко распаковать и получить исходный код. - В бизнесе данные чата приложений для обмена мгновенными сообщениями хранятся локально, хотя используется зашифрованная версия sqlite3. Но получение исходного кода означает знание ключа, а шифрование базы данных бесполезно.
найти решение
асарское шифрование
Просматривая github и Stack Overflow, я обнаружил, что схема защиты исходного кода Electron обсуждается уже давно.
Подводя итог, чиновник не намерен предоставлять решение. Авторы считают, что независимо от того, какая форма используется для шифрования файла пакета, ключ всегда должен быть помещен в пакет. .
Продолжайте листать, какие-то большие ребята на отечественном форуме пытались решить эту проблему, начиная с упаковки asar, но так и не разобрались. .
Правильный способ шифрования и упаковки электрона
Просто поймите идею большого парня: проанализируйте исходный код asar, зашифруйте записанный файл с помощью алгоритма шифрования перед записью файла, когда asar упакован; добавьте соответствующий алгоритм расшифровки файла, где asar.js читает файл; заголовок файла asar json зашифрован, так что официальный асар не распаковать.
Я понял идею, но не знаю, как начать. Заинтересованная детская обувь может взять на себя инициативу, чтобы оставить сообщение, чтобы спросить. .
аддоны инкапсулируют основной код
Кто-то в электронной проблеме предположил, что надстройки nodejs можно использовать для инкапсуляции основного кода. Addons — это подключаемый модуль для nodejs для реализации кроссплатформенного вызова нативного кода, поскольку основной целью защиты исходного кода является повышение безопасности, хранение ключевых полей, таких как ключи базы данных, в нативном коде и повышение порога взлома.
выполнить
Синтаксис C++ практически забыт, давайте сначала реализуем простую бизнес-практику: JS передает объект информации о пользователе, C++ читает объект и после обработки возвращает ключ, соответствующий базе данных.
Преобразование типов между Nodejs и C++ обеспечивается API версии 8. Подробную информацию см.Преобразование типов между Node.js и C++.
// key.cc
#include <node.h>
namespace key {
using v8::FunctionCallbackInfo;
using v8::Isolate;
using v8::Local;
using v8::NewStringType;
using v8::Object;
using v8::String;
using v8::Value;
void GetKeys(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = args.GetIsolate();
// 判断js传递的参数是否为对象
if (!args[0]->IsObject()) {
printf("not Object\n");
}
// 新建对象,将cfg和id绑定到对象
Local<String> cfgKey = v8::String::NewFromUtf8(isolate, "testxxx");
Local<Object> keyObj = v8::Object::New(isolate);
keyObj->Set(v8::String::NewFromUtf8(isolate, "cfgKey"), cfgKey);
// 读取js传递的对象
Local<Object> userObj = Local<Object>::Cast(args[0]);
Local<Value> id = userObj->Get(String::NewFromUtf8(isolate, "id"));
keyObj->Set(v8::String::NewFromUtf8(isolate, "id"), id);
args.GetReturnValue().Set(keyObj);
}
void GetUidByUserInfo(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = args.GetIsolate();
Local<Object> userObj = Local<Object>::Cast(args[0]);
Local<Value> id = userObj->Get(String::NewFromUtf8(isolate, "id"));
args.GetReturnValue().Set(id);
}
void Initialize(Local<Object> exports) {
NODE_SET_METHOD(exports, "getKey", GetKeys);
NODE_SET_METHOD(exports, "getUserKey", GetUidByUserInfo);
}
NODE_MODULE(NODE_GYP_MODULE_NAME, Initialize)
}
key.cc
В , представлено два простых метода, а именно: получить все ключевые объекты и получить ключи отдельных пользователей.Конечно, это всего лишь простое отображение бизнес-логики. В надстройках Nodejs интерфейсы инициализируются функциями по следующему шаблону:
void Initialize(Local<Object> exports);
NODE_MODULE(NODE_GYP_MODULE_NAME, Initialize)
NODE_GYP_MODULE_NAME
, это имя модуля, установленное в binding.gyp. Nodejs не может напрямую вызывать файлы C++, его необходимо скомпилировать в бинарные файлы через node-gyp Binding.gyp — это файл конфигурации сборки, аналогичный JSON. Создайте новый файл в корневом каталоге:
{
"targets": [
{
"target_name": "dbkey",
"sources": [ "key.cc" ]
}
]
}
Установите node-gyp и связанные с ним зависимости. Вводите команды одну за другойnode-gyp configure
,node-gyp build
После успеха создайте каталог сборки и получите двоичный файл dbkey.node.
Затем пишем js-тест.
const dbKey = require('./build/Release/dbkey');
const userInfo = {
id: '123456',
};
console.log(dbKey.getKey()); // { cfgKey: 'testxxx', id: '123456' }
console.log(dbKey.getUserKey(userInfo)); // 123456
С помощью require() мы можем вызывать модули C++.
Тем не менее, dbkey.node в настоящее время не может быть напрямую загружен в электрон для использования, нам нужно перекомпилировать плагин с файлами заголовков, связанными с электронами.
node-gyp rebuild --target=1.7.11 --arch=x64 --target_platform=darwin --dist-url=https://atom.io/download/atom-shell
Перекомпилируйте в соответствии с вашим номером электронной версии (target) и платформой (target_platform).
ps. Поскольку существует много версий Nodejs, а его API V8 не полностью согласован, рекомендуется использовать логику C++.NAN, NAN инкапсулировала V8 API, так что нам не нужно заботиться о версии. Нативные модули, используемые в нашем проекте, такие как canvas, sqlite и т. д., также используют NAN в своем исходном коде.
Суммировать
Использование надстроек C++ для инкапсуляции основного бизнес-кода может в определенной степени повысить безопасность исходного кода. Однако предыдущий процесс упаковки необходимо модифицировать, что принесет некоторые неудобства при разработке и отладке. Давайте посмотрим, как выбирает бизнес.