elektroyar
elektroyar личный блог
08 апреля 2021, 00:52

Зашифрованный и сжатый JSON с комментариями в качестве файла конфигурации

В процессе разработки ПО для трейдинга столкнулся с тем, что программа должна иметь целую кучу файлов конфигурации, содержание которых хотелось бы скрыть от пользователя. Это могут быть настройки стратегий, параметры авторизации на сервере, текст для разных языков интерфейса и т.д.

Для файлов конфигурации я уже давно использую файлы с JSON. Очень удобная вещь. Осталось лишь добавить поддержку комментариев и зашифровать текст при помощи алгоритма AES. А для большей красоты еще и сжать текст перед шифровкой алгоритмом brotli.

Сказано — сделано. Встречайте — crypto-jsonпроект на гитхабе. Репозиторий содержит готовый редактор JSON с комментариями, который может также сохранить текст в зашифрованном виде. Настройки сжатия и шифрования можно задать перед сохранением файла и во время открытия. Также редактор позволяет сделать проверку JSON и может подсвечивать проблемные места.

Зашифрованный и сжатый JSON с комментариями в качестве файла конфигурации
Зашифрованный и сжатый JSON с комментариями в качестве файла конфигурации


Работа с зашифрованными JSON файлами в C++


Для использования зашифрованных файлов в программе библиотека содержит простые функции. Покажу пример кода, который раскрывает почти все возможности библиотеки:

#include <crypto-json/crypto-json.hpp>

//...

/* загрузим текст из файла test.json */
std::string src;
crypto_json::load_file("test.json", src);

/* настроим тип шифрования - алгоритм AES в режиме CFB, длина ключа 256 */
crypto_json::EncryptionAlgorithmType type = crypto_json::EncryptionAlgorithmType::USE_AES_CFB_256;

/* создадим ключ и инициализирующий вектор длиной 256 */
std::array<uint8_t, 32> key;
std::array<uint8_t, 32> iv;

/* для примера, зададим случайный ключ и инициализирующий вектор */
crypto_json::generate_key_or_iv(key);
crypto_json::generate_key_or_iv(iv);

/* преобразуем ключ и инициализирующий вектор в hex-строку и выведем на экран */
std::cout << "key:" << std::endl << crypto_json::to_hex_string(key) << std::endl;
std::cout << "iv:" << std::endl << crypto_json::to_hex_string(iv) << std::endl;

/* преобразуем hex-строку в ключ и инициализирующий вектор */
std::array<uint8_t, 32> key2;
std::array<uint8_t, 32> iv2;
crypto_json::convert_hex_string_to_byte(crypto_json::to_hex_string(key), key2);
crypto_json::convert_hex_string_to_byte(crypto_json::to_hex_string(iv), iv2);

/* зашифруем текст и сожмьем его при помощи алгоритма brotli */
std::string crypto_json_str = crypto_json::to_crypto_json(src, key, iv, type, true);

/* сравним размеры зашифрованного текста и оригинального */
std::cout << "src size:" << src.size() << std::endl;
std::cout << "crypto json size: " << crypto_json_str.size() << std::endl;

/* дешифруем crypto json */
std::string str = crypto_json::to_string(crypto_json_str, key, iv, type, true);

/* дешифруем crypto json в класс json библиотеки nlohmann/json.hpp */
nlohmann::json j = crypto_json::to_json(crypto_json_str, key, iv, type, true);
std::cout << "to json:" << std::endl << j << std::endl;
	
/* зашифруем данные класса библиотеки nlohmann/json.hpp */ 
std::string crypto_json_str2 = crypto_json::to_crypto_json(j, key, iv, type, true);
31 Комментарий
  • 3Qu
    08 апреля 2021, 02:46

    JSON эт неплохо. Но зачем его сжимать не пойму. Неужели такой громадный?
    А шифровать? — от кого?

      • Kolya Marketolog
        08 апреля 2021, 07:42
        elektroyar, вы сильно переоцениваете интеллектуальные способности «трейдеров», покупающих стратегии…
      • Игорь Шумилов
        08 апреля 2021, 13:50
        elektroyar, а разве на сами трейдеры изначально будут вводить все эти данные через интерфейс программы?
          • ch5oh
            08 апреля 2021, 15:44
            elektroyar, можно задуматься о том, насколько законна передача такой информации на Ваш сервер и достаточно ясно ли понимают Ваши клиенты, что Вы храните и раскладываете у себя на машине все их позиции и сделки.
  • Алексей Никитин
    08 апреля 2021, 08:42
    От она удача!!!
  • Дедал
    08 апреля 2021, 09:06
    Zip с паролем ничем не хуже. И не надо тянуть лишние зависимости.
    Велосипед
  • CloseToAlgoTrading
    08 апреля 2021, 12:00
    Плюс за старания :), но не совсем понятна практическая сторона вопроса. Если вы не правите конфиг файлы руками, то сохраняйте все в бинарный формат. Сделали свою структуру данных и сохранили как байткод, никто и не разберется что там и где :)
      • CloseToAlgoTrading
        08 апреля 2021, 15:34
        elektroyar, ну вы ее тоже можите кодировать :). Но я ничего против вашего способа не имею. 
  • Игорь Шумилов
    08 апреля 2021, 13:51
     А сами ключи как хранятся? ;)
      • Игорь Шумилов
        08 апреля 2021, 16:08
        elektroyar, т.е. захардкожены? А значит берётся дизассемблер и находится тот кусок памяти, откуда читается ключ :)
  • ch5oh
    08 апреля 2021, 14:26
    Само использование С++ — достаточная защита.
      • ch5oh
        08 апреля 2021, 15:45
        elektroyar, ага, есть такие таланты. Хорошо, что они не торгуют. 
  • _sg_
    08 апреля 2021, 15:11
    Все пральна. Защищаться надо.
    Когда у меня было распространяемое ПО,
    то я критически важные сборки через WEB на клиентские места загружал.
    То есть на клиентском месте не было важных сборок, а ПО работало.
    Чудеса.
    А на сервере моем было видно кто и что загружает, на какие IP.
    Если IP не зарегистрированы, то сразу «футбол».
    И maintance значительно упрощалось.
    Все сборки лежали в одном месте на сервере, были «up to date».
    ТО есть пользователь не нуждался в дополнительных update-ах, они по определению были всегда свежими.
    • ch5oh
      08 апреля 2021, 15:48
      _sg_, это же видно в дебаггере, что какие-то сборки скачаны. А дальше дело техники. Ну и привязка по IP — довольно жесткое ограничение по нашим временам.
      • _sg_
        08 апреля 2021, 16:00
        ch5oh, 
        нет конкретного назавания сборок.
        Для каждого пользователя загружается конкретная конфигурация, которая состоит из сборок, файлов конфигурации и др вспомогательных файлов. Все загружается  в сжатом виде с ключом.
        Все сборки сразу грузятся в память, на диске не сохраняются.
        В дебагере, конечно, можно посмотреть что «что-то» загружается,  а что конкретно летит определить сложно.
        И пользователь не в курсе, что сборки грузятся извне.
        Он думает, что все файлы есть на диске.
        Специалист, конечно, раскопает. Но обычный, или даже продвинутый пользователь не справится.
      • _sg_
        08 апреля 2021, 16:39
        ch5oh,
        Еще есть способы борьбы с дебагерами. Путем замера времени исполнения определенных частей кода. Замеры делаются обычно в нескольких разных потоках одновременно, не в основном потоке выполнения.
        Если время исполнения кода превышено, то значит дебажат ...
        Но у меня этого нет, поэтому нюансов не знаю. Сам не пробовал.
        Но идея вроде хороша на первый взгляд.

Активные форумы
Что сейчас обсуждают

Старый дизайн
Старый
дизайн