mirror of
https://github.com/Obfuscator-Collections/VMProtect.git
synced 2025-08-02 22:40:10 +03:00
first commit
Version 3.x.x
This commit is contained in:
79
help/ru/manager/keygen/algorithms.htm
Normal file
79
help/ru/manager/keygen/algorithms.htm
Normal file
@@ -0,0 +1,79 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<link rel="Stylesheet" type="text/css" href=
|
||||
"../../default.css" />
|
||||
<meta http-equiv="Content-Type" content=
|
||||
"text/html; charset=utf-8" />
|
||||
|
||||
<title>Алгоритмы шифрования серийных номеров</title>
|
||||
<style type="text/css">
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>Алгоритмы шифрования серийных номеров</h1>
|
||||
|
||||
<p>Надежность ключей системы лицензирования основывается на
|
||||
применении асимметричных алгоритмов шифрования. В текущей версии
|
||||
реализован алгоритм RSA с длиной ключа от 1024 до 16384 бит. В
|
||||
будущих версиях планируется добавление других алгоритмов,
|
||||
основанных на ECC, а также схем, совмещающих симметричные и
|
||||
асимметричные шифры.</p>
|
||||
|
||||
<p>Используемый алгоритм уникален для каждого продукта. Ключи,
|
||||
созданные с одним алгоритмом, не подойдут к другому, поэтому
|
||||
смена алгоритмов после создания хоть одной лицензии не
|
||||
допускается. Модуль защиты, располагающийся в защищаемой
|
||||
программе, "знает" каким алгоритмом должен быть зашифрован
|
||||
серийный номер и не примет ключ, созданный другим алгоритмом или
|
||||
тем же алгоритмом, но с другими параметрами (скажем, с другой
|
||||
длиной ключа).</p>
|
||||
|
||||
<h3>Алгоритм RSA</h3>
|
||||
|
||||
<p>Шифрование серийного номера алгоритмом RSA происходит по
|
||||
следующей схеме:</p>
|
||||
|
||||
<ul>
|
||||
<li><strong>Добавление случайных данных в начало
|
||||
номера</strong> - метод основывается на RFC2313, однако
|
||||
реализация немного отличается от описаной там. В начало
|
||||
серийного номера добавляютя байты: 00 02 NN...NN 00, где NN..NN
|
||||
- от 8 до 16 случайных ненулевых байт. Количество байт
|
||||
выбирается случайным, однако принимается во внимание длина
|
||||
серийного номера и максимальная вместительность ключа.</li>
|
||||
|
||||
<li><strong>Добавление случайных данных в конец номера</strong>
|
||||
- окончательное количество байт в серийном номере должно
|
||||
равняться количеству бит в ключах алгоритма, деленному на 8.
|
||||
Серийный номер дополняется до этого числа байт случайными
|
||||
данными. В результате получается следующий формат серийного
|
||||
номера: 00 02 NN..NN 00 DD..DD MM..MM, где NN - набор случайных
|
||||
ненулевых байтов, DD - исходный серийный номер, MM -набор
|
||||
случайных байтов (в т.ч. и нулевых). Суммарная длина
|
||||
последовательности должна равняться количеству бит,
|
||||
применяемому в алгоритме, деленному на 8.</li>
|
||||
|
||||
<li><strong>Шифрование</strong> - производится по стандатной
|
||||
схеме, реализованной во многих библиотеках, работающих с
|
||||
большими числами. Генератор на PHP содержит всю необходимую
|
||||
информацию в открытом виде.</li>
|
||||
|
||||
<li><strong>Упаковка</strong> - полученный после шифрования
|
||||
набор байт кодируется в base-64 - это и есть серийный номер,
|
||||
который отправляется покупателю.</li>
|
||||
</ul><br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<hr noshade="noshade" size="1" />
|
||||
|
||||
<div align="center">
|
||||
© 2006-2015 Copyright VMProtect Software
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
121
help/ru/manager/keygen/index.htm
Normal file
121
help/ru/manager/keygen/index.htm
Normal file
@@ -0,0 +1,121 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<link rel="Stylesheet" type="text/css" href=
|
||||
"../../default.css" />
|
||||
<meta http-equiv="Content-Type" content=
|
||||
"text/html; charset=utf-8" />
|
||||
|
||||
<title>Генераторы ключей</title>
|
||||
<style type="text/css">
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>Генераторы ключей</h1><strong>Зачем они нужны?</strong>
|
||||
|
||||
<p>Помимо VMProtect, серийные номера могут генерироваться другими
|
||||
программами - генераторами. Это нужно для автоматизации выдачи
|
||||
номеров без участия человека. Покупатель покупает продукт,
|
||||
регистратор делает HTTP-запрос на сайт производителя, там
|
||||
запускается программа-генератор и на основе данных о покупателе
|
||||
формирует серийный номер. Номер отправляется покупателю и
|
||||
производителю. Производитель вносит его в базу VMProtect вручную,
|
||||
через окно импорта лицензий.</p><strong>Принцип работы</strong>
|
||||
|
||||
<p>Система лицензирования VMProtect построена на асимметричных
|
||||
алгоритмах, поэтому для генерации серийных номеров требуется
|
||||
секретный ключ продукта. Этот ключ можно экспортировать в окне
|
||||
свойств продукта и передать программе-генератору подходящим для
|
||||
нее способом.</p>
|
||||
|
||||
<p>Программа-генератор вызывается регистратором через
|
||||
HTTP-запрос. Генератор на PHP может быть вызван напрямую,
|
||||
генератор в виде DLL - косвенно, но алгоритм остается одним и тем
|
||||
же:</p>
|
||||
|
||||
<ul>
|
||||
<li>Получить данные о пользователе от регистратора</li>
|
||||
|
||||
<li>Добавить необходимую информацию, которую указал
|
||||
производитель</li>
|
||||
|
||||
<li>Сформировать серийный номер</li>
|
||||
|
||||
<li>Зашифровать его одним из алгоритмов</li>
|
||||
|
||||
<li>Передать результат регистратору</li>
|
||||
</ul><strong>Существуют ли готовые генераторы?</strong>
|
||||
|
||||
<p>С системой лицензирования поставляется три готовых генератора
|
||||
серийных номеров <a href="keygen_dll.htm">в виде DLL</a>,
|
||||
<a href="keygen_net.htm">для платформы .Net</a> и <a href=
|
||||
"keygen_php.htm">реализованный на PHP</a>.</p><strong>Можно ли
|
||||
сделать свой генератор?</strong>
|
||||
|
||||
<p>Можно. Формат серийного номера находится <a href=
|
||||
"serial_format.htm">здесь</a>, алгоритмы шифрования серийного
|
||||
номера описаны <a href=
|
||||
"algorithms.htm">здесь</a>.</p><strong>Насколько это
|
||||
безопасно?</strong>
|
||||
|
||||
<p>В общем случае - вполне безопасно. Однако есть несколько
|
||||
рекомендаций, которым стоит следовать:</p>
|
||||
|
||||
<ul>
|
||||
<li><strong>Используйте протокол HTTPS</strong> - если ваш
|
||||
регистратор умеет делать запрос по HTTPS, а ваш хостинг
|
||||
позволяет отвечать на такие запросы, то этот вариант
|
||||
предпочтительнее обычного HTTP, т.к. поток данных будет
|
||||
зашифрован и сгенерированный серийный номер сможет получить
|
||||
только регистратор.</li>
|
||||
|
||||
<li><strong>"Спрячьте" генератор</strong> - убедитесь, что
|
||||
генератор нельзя вызвать случайно. Адрес
|
||||
www.site.com/keygen.php - плохая идея. А вот
|
||||
www.site.com/abc123.php - уже лучше. Убедитесь, что на
|
||||
генератор нет внешних ссылок, что он не показывается при
|
||||
просмотре содержимого директории сайта и не помещайте его в
|
||||
служебные файлы типа robots.txt. Чем меньше известно о
|
||||
расположении генератора - тем лучше. Как вариант - можно
|
||||
вынести генератор на другой сайт.</li>
|
||||
|
||||
<li><strong>Убедитесь, что вас вызывает регистратор</strong> -
|
||||
в программе, обрабатывающей запрос от регистратора, необходимо
|
||||
проверить IP-адрес вызывающей стороны. Обычно регистраторы
|
||||
публикуют список адресов, с которых они могут вызвать
|
||||
генератор. Найдите такой у вашего регистратора и добавьте
|
||||
проверку. В случае несовпадения адреса, лучше не выдавать
|
||||
понятных ошибок. Не возвращайте ничего или верните ошибку 404.
|
||||
Не давайте повода понять, почему вызов оказался неудачен.</li>
|
||||
|
||||
<li><strong>Проверяйте входные параметры</strong> - в
|
||||
настройках продукта у регистратора обычно дается возможность
|
||||
указать строку запроса, который регистратор будет делать для
|
||||
получения лицензии. Скажем, вы хотите получать имя
|
||||
пользователя, адрес его электронной почты, дату продажи и номер
|
||||
заказа. Убедитесь при получении запроса, что все параметры
|
||||
переданы и что все они имеют корректный формат. Не отвечайте на
|
||||
запросы с ошибками. О любых ошибках уведомляйте себя отправкой
|
||||
e-mail со всеми параметрами, с которыми был вызван генератор.
|
||||
Это поможет разобраться в причинах проблемы.</li>
|
||||
|
||||
<li><strong>Добавьте "пароль"</strong> - укажите в запросе,
|
||||
посылаемом регистратором, дополнительный параметр - пароль. С
|
||||
неочевидным именем и значением. Проверяйте его на принимающей
|
||||
стороне. В случае несовпадения или отсутствия - не генерируйте
|
||||
номер.</li>
|
||||
</ul><br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<hr noshade="noshade" size="1" />
|
||||
|
||||
<div align="center">
|
||||
© 2006-2015 Copyright VMProtect Software
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
284
help/ru/manager/keygen/keygen_dll.htm
Normal file
284
help/ru/manager/keygen/keygen_dll.htm
Normal file
@@ -0,0 +1,284 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<link rel="Stylesheet" type="text/css" href=
|
||||
"../../default.css" />
|
||||
<meta http-equiv="Content-Type" content=
|
||||
"text/html; charset=utf-8" />
|
||||
|
||||
<title>Генератор ключей: Windows-версия</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>Генераторы ключей: Windows-версия</h1>
|
||||
|
||||
<h3>Описание</h3>
|
||||
|
||||
<p>Генератор для Windows представляет собой DLL-файлы для
|
||||
платформ x86 и x64, заголовочный файл языка C и lib-файл,
|
||||
совместимый с MSVC. Таким образом, библиотека может быть как слинкована статически, так
|
||||
и загружаться динамически.</p>
|
||||
|
||||
<p>Все файлы генератора находятся в каталоге
|
||||
<strong>Keygen\DLL</strong>, там же находится тестовое
|
||||
приложение, которое генерирует серийные номера.</p>
|
||||
|
||||
<h3>API генератора</h3>
|
||||
|
||||
<p>Генератор экспортирует всего две функции: одна непосредственно
|
||||
генерирует серийный номер, вторая - освобождает память,
|
||||
выделенную первой. Начнем с первой и основной функции:</p>
|
||||
<pre class="code"><strong>VMProtectErrors</strong> __stdcall <strong>VMProtectGenerateSerialNumber</strong>(
|
||||
<strong>VMProtectProductInfo *</strong> pProductInfo,
|
||||
<strong>VMProtectSerialNumberInfo *</strong> pSerialInfo,
|
||||
<strong>char **</strong> pSerialNumber
|
||||
);
|
||||
</pre>
|
||||
|
||||
<p>Первый параметр - указатель на структуру
|
||||
<strong>VMProtectProductInfo</strong>, содержимое которой
|
||||
выгружается в VMProtect (см. <a href=
|
||||
"../licenses.htm#export">Экспорт параметров продукта</a>).
|
||||
Структура содержит приватный ключ продукта, используемый алгоритм
|
||||
и количество бит, а также идентификатор продукта. Подробнее о
|
||||
заполнении этой структуры написано ниже.</p>
|
||||
|
||||
<p>Второй параметр - указатель на структуру
|
||||
<strong>VMProtectSerialNumberInfo</strong>, содержимое которой
|
||||
переносится в генерируемый серийный номер. Структура содержит все
|
||||
поля серийного номера, а также битовую маску, определяющую какие
|
||||
именно поля должны быть записаны в серийный номер.</p>
|
||||
<pre class="code">struct <strong>VMProtectSerialNumberInfo</strong>
|
||||
{
|
||||
<strong>INT</strong> flags;
|
||||
<strong>wchar_t *</strong> pUserName;
|
||||
<strong>wchar_t *</strong> pEMail;
|
||||
<strong>DWORD</strong> dwExpDate;
|
||||
<strong>DWORD</strong> dwMaxBuildDate;
|
||||
<strong>BYTE</strong> nRunningTimeLimit;
|
||||
<strong>char *</strong> pHardwareID;
|
||||
<strong>size_t</strong> nUserDataLength;
|
||||
<strong>BYTE *</strong> pUserData;
|
||||
};
|
||||
</pre>
|
||||
|
||||
<p>Поле <strong>flags</strong> содержит битовые флаги из набора
|
||||
<strong>VMProtectSerialNumberFlags</strong>, описанного перед
|
||||
структурой:</p>
|
||||
|
||||
<ul>
|
||||
<li><strong>HAS_USER_NAME</strong> - поместить в серийный номер
|
||||
имя пользователя, находящееся в переменной
|
||||
<strong>pUserName</strong>.</li>
|
||||
|
||||
<li><strong>HAS_EMAIL</strong> - поместить в серийный номер
|
||||
e-mail пользователя, находящийся в переменной
|
||||
<strong>pEMail</strong>.</li>
|
||||
|
||||
<li><strong>HAS_EXP_DATE</strong> - серийный номер перестанет
|
||||
действовать поле окончания дня, указанного в переменной
|
||||
<strong>dwExpDate</strong>.</li>
|
||||
|
||||
<li><strong>HAS_MAX_BUILD_DATE</strong> - серийный номер будет
|
||||
подходить только к версиям продукта, созданным до даты,
|
||||
указанной в переменной <strong>dwMaxBuildDate</strong>.</li>
|
||||
|
||||
<li><strong>HAS_TIME_LIMIT</strong> - программа перестанет
|
||||
работать по истечении времени, указанного в переменной
|
||||
<strong>nRunningTimeLimit</strong> (время указывается в минутах
|
||||
и не может превышать 255).</li>
|
||||
|
||||
<li><strong>HAS_HARDWARE_ID</strong> - программа будет работать
|
||||
только на оборудовании с идентификатором, указанным в
|
||||
переменной <strong>pHardwareID</strong>.</li>
|
||||
|
||||
<li><strong>HAS_USER_DATA</strong> - поместить в серийный номер
|
||||
пользовательские данные длинной
|
||||
<strong>nUserDataLength</strong>, расположенные по адресу,
|
||||
указанному в переменной <strong>pUserData</strong>.</li>
|
||||
</ul>
|
||||
|
||||
<p>Третий параметр - указатель на указатель. Туда будет записан
|
||||
адрес сгенерированного серийного номера. После генерации номер
|
||||
необходимо скопировать, а адрес передать во вторую функцию API
|
||||
генератора, которая освободит занимаемую серийным номером
|
||||
память.</p>
|
||||
<pre class="code"><strong>void</strong> __stdcall <strong>VMProtectFreeSerialNumberMemory</strong>(<strong>char *</strong> pSerialNumber);
|
||||
</pre>
|
||||
|
||||
<p>Функция <strong>VMProtectGenerateSerialNumber</strong>
|
||||
возвращает значение типа <strong>VMProtectErrors</strong>,
|
||||
содержащее 0 в случае успешной генерации номера или код ошибки в
|
||||
противном случае. Возможны следующие коды ошибок:</p>
|
||||
|
||||
<ul>
|
||||
<li><strong>ALL_RIGHT</strong> - ошибок нет, номер сгенерирован
|
||||
успешно.</li>
|
||||
|
||||
<li><strong>UNSUPPORTED_ALGORITHM</strong> - в первом параметре
|
||||
функции передан некорректный алгоритм шифрования ключа.</li>
|
||||
|
||||
<li><strong>UNSUPPORTED_NUMBER_OF_BITS</strong> - в первом
|
||||
параметре функции передано некорректное количество бит в
|
||||
ключе.</li>
|
||||
|
||||
<li><strong>USER_NAME_IS_TOO_LONG</strong> - длина имени
|
||||
пользователя в кодировке UTF-8 превысила 255 байт.</li>
|
||||
|
||||
<li><strong>EMAIL_IS_TOO_LONG</strong> - длина e-mail
|
||||
пользователя в кодировке UTF-8 превысила 255 байт.</li>
|
||||
|
||||
<li><strong>USER_DATA_IS_TOO_LONG</strong> - длина
|
||||
пользовательских данных превышает 255 байт.</li>
|
||||
|
||||
<li><strong>HWID_HAS_BAD_SIZE</strong> - идентификатор
|
||||
оборудования имеет некорректный размер.</li>
|
||||
|
||||
<li><strong>PRODUCT_CODE_HAS_BAD_SIZE</strong> - идентификатор
|
||||
продукта, переданный в первом параметре функции, имеет неверный
|
||||
размер.</li>
|
||||
|
||||
<li><strong>SERIAL_NUMBER_TOO_LONG</strong> - серийный номер
|
||||
слишком длинный и не помещается в указанное в алгоритме количество
|
||||
бит.</li>
|
||||
|
||||
<li><strong>BAD_PRODUCT_INFO</strong> - первый параметр функции
|
||||
некорректен или NULL.</li>
|
||||
|
||||
<li><strong>BAD_SERIAL_NUMBER_INFO</strong> - второй параметр
|
||||
функции некорректен или NULL.</li>
|
||||
|
||||
<li><strong>BAD_SERIAL_NUMBER_CONTAINER</strong> - третий
|
||||
параметр функции не указывает на ячейку памяти для записи
|
||||
адреса серийного номера.</li>
|
||||
|
||||
<li><strong>NOT_EMPTY_SERIAL_NUMBER_CONTAINER</strong> - третий
|
||||
параметр функции не указывает на пустую ячейку, в ячейке должно
|
||||
быть значение NULL.</li>
|
||||
|
||||
<li><strong>BAD_PRIVATE_EXPONENT</strong> - значение приватной
|
||||
экспоненты в первом параметре функции некорректно.</li>
|
||||
|
||||
<li><strong>BAD_MODULUS</strong> - значение модуля в первом
|
||||
параметре функции некорректно.</li>
|
||||
</ul>
|
||||
|
||||
<p>Ошибки делятся на две категории: те, что связаны с
|
||||
некорректными параметрами или с содержимым первого параметра
|
||||
функции, и все остальные. Ошибки первой категории редки и
|
||||
являются признаком некорректной настройки структуры. Имеет смысл
|
||||
выгрузить информацию о продукте повторно и убедиться, что
|
||||
структура заполняется правильно. Пример правильного заполнения
|
||||
приведен ниже.</p>
|
||||
|
||||
<p>Ошибки второй категории связаны с попыткой вместить в ключ
|
||||
больше данных, чем это возможно ввиду его размера. В таком случае
|
||||
разумно будет отправить регистратору вместо ключа текст "Ключ
|
||||
будет выслан в течение суток", а всю необходимую информацию
|
||||
отправить себе по почте. Ключ в таком случае генерируется в
|
||||
VMProtect в ручном режиме, какие-то данные обрезаются, чтобы
|
||||
уместить все необходимое в максимальный размер
|
||||
ключа.</p>
|
||||
|
||||
<h3>Пример использования</h3>
|
||||
|
||||
<p>Ниже приведен пример кода, который вызывает две вышеописанные
|
||||
функции и генерирует серийный номер. Обратите внимание на блок
|
||||
кода, расположенный в самом начале. Пример не будет работать пока
|
||||
вы не замените его на блок, выгруженный для продукта из
|
||||
VMProtect:</p>
|
||||
<pre class="code">//////////////////////////////////////////////////////////////////////////
|
||||
// !!! this block should be generated by VMProtect !!! ///
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
<strong>VMProtectAlgorithms</strong> g_Algorithm = ALGORITHM_RSA;
|
||||
<strong>size_t</strong> g_nBits = 0;
|
||||
<strong>byte</strong> g_vModulus[1];
|
||||
<strong>byte</strong> g_vPrivate[1];
|
||||
<strong>byte</strong> g_vProductCode[1];
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
<strong>int</strong> _tmain(<strong>int</strong> argc, <strong>_TCHAR*</strong> argv[])
|
||||
{
|
||||
<strong>VMProtectProductInfo</strong> pi;
|
||||
pi.algorithm = g_Algorithm;
|
||||
pi.nBits = g_nBits;
|
||||
pi.nModulusSize = sizeof(g_vModulus);
|
||||
pi.pModulus = g_vModulus;
|
||||
pi.nPrivateSize = sizeof(g_vPrivate);
|
||||
pi.pPrivate = g_vPrivate;
|
||||
pi.nProductCodeSize = sizeof(g_vProductCode);
|
||||
pi.pProductCode = g_vProductCode;
|
||||
|
||||
<strong>VMProtectSerialNumberInfo</strong> si = {0};
|
||||
si.flags = HAS_USER_NAME | HAS_EMAIL;
|
||||
si.pUserName = L"John Doe";
|
||||
si.pEMail = L"john@doe.com";
|
||||
<strong>char *</strong> pBuf = NULL;
|
||||
<strong>VMProtectErrors</strong> res = <strong>VMProtectGenerateSerialNumber</strong>(&pi, &si, &pBuf);
|
||||
<strong>if</strong> (res == ALL_RIGHT)
|
||||
{
|
||||
<strong>printf</strong>("Serial number:\n%s\n", pBuf);
|
||||
<strong>VMProtectFreeSerialNumberMemory</strong>(pBuf);
|
||||
}
|
||||
else
|
||||
{
|
||||
<strong>printf</strong>("Error: %d\n", res);
|
||||
}
|
||||
|
||||
<strong>return</strong> 0;
|
||||
}
|
||||
</pre>
|
||||
|
||||
<p>Этот пример с проектом для Microsoft Visual Studio находится в
|
||||
каталоге <strong>Keygen\DLL\Example</strong>, ниже будут описаны
|
||||
наиболее интересные места кода.</p>
|
||||
|
||||
<p>Первые строчки функции <strong>main</strong> заполняют
|
||||
структуру <strong>VMProtectProductInfo</strong> данными,
|
||||
выгруженными из VMProtect. Этот код стандартен, его не следует
|
||||
менять во избежание появления ошибок. Далее создается структура
|
||||
<strong>VMProtectSerialNumberInfo</strong>, в поле флагов
|
||||
выставляется комбинация из битов имени пользователя и e-mail.
|
||||
Строчкой ниже в соответствующие поля структуры заносятся значения
|
||||
имени пользователя и пароля. Обратите внимание, что значения
|
||||
принимаются в кодировке UNICODE. Генератор ключей внутри
|
||||
преобразует их в кодировку UTF-8.</p>
|
||||
|
||||
<p>Далее описывается переменная-указатель, куда будет записан
|
||||
адрес сгенерированного ключа, и вызывается функция
|
||||
<strong>VMProtectGenerateSerialNumber</strong>, после чего
|
||||
анализируется код возврата. Если ошибок нет, то сгенерированный
|
||||
номер печатается на консоль и вызывается функция осовобождения
|
||||
памяти.</p>
|
||||
|
||||
<h3>Остальные поля структуры VMprotectSerialNumberInfo</h3>
|
||||
|
||||
<p>Некоторые поля структуры требуют дополнительных поясненений. К
|
||||
примеру, поля <strong>dwExpDate</strong> и
|
||||
<strong>dwMaxBuildDate</strong> содержат даты в определенном
|
||||
формате: <strong>0xYYYYMMDD</strong>, т.е. год хранится в старшем
|
||||
слове, а месяц и день в старшем и младшем байтах младшего слова.
|
||||
Для формирования такого числа описан макрос <strong>MAKEDATE(y,
|
||||
m, d)</strong>, который можно вызвать так: <strong>MAKEDATE(2010,
|
||||
05, 12)</strong>.</p>
|
||||
|
||||
<p>В поле <strong>pHardwareID</strong> должен быть записан
|
||||
указатель на строку, которую вернул метод
|
||||
<strong>VMProtectGetCurrentHWID</strong> из SDK
|
||||
лицензирования.</p><br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<hr noshade="noshade" size="1" />
|
||||
|
||||
<div align="center">
|
||||
© 2006-2015 Copyright VMProtect Software
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
115
help/ru/manager/keygen/keygen_net.htm
Normal file
115
help/ru/manager/keygen/keygen_net.htm
Normal file
@@ -0,0 +1,115 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<link rel="Stylesheet" type="text/css" href=
|
||||
"../../default.css" />
|
||||
<meta http-equiv="Content-Type" content=
|
||||
"text/html; charset=utf-8" />
|
||||
|
||||
<title>Генератор ключей: .Net-версия</title>
|
||||
<style type="text/css">
|
||||
/*<![CDATA[*/
|
||||
div.c2 {text-align: center}
|
||||
p.c1 {color:red;}
|
||||
/*]]>*/
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>Генераторы ключей: .Net-версия</h1>
|
||||
|
||||
<h3>Описание</h3>
|
||||
|
||||
<p>.Net-версия генератора ключей преставляет собой сборку,
|
||||
содержащую все необходимое для генерации серийных номеров.
|
||||
Исходные коды находятся в каталоге <strong>Keygen\Net</strong> в
|
||||
виде двух проектов: KeyGen (непосредственно генератор серийных
|
||||
номеров) и Usage (пример использования генератора).</p>
|
||||
|
||||
<p class="c1">Генератор поставляется в исходных кодах, чтобы
|
||||
иметь возможность пересобрать его под нужную версию .Net
|
||||
Framework, однако крайне не рекомендуется вносить изменения в его
|
||||
код. В будущих версиях VMProtect возможно добавление новых
|
||||
возможностей в генератор, что приведет к необходимости повторной
|
||||
модификации кода. Также возможно появление трудноуловимых ошибок.
|
||||
В случае нахождения ошибки в оригинальном коде генератора или
|
||||
пожеланий по его улучшению - обращайтесь в службу
|
||||
поддержки.</p>
|
||||
|
||||
<h3>Использование генератора</h3>
|
||||
|
||||
<p>Возьмите за основу код из проекта <strong>Usage</strong>,
|
||||
добавьте в Ваш проект ссылку на сборку VMProtect.KeyGen.dll,
|
||||
после чего Вы сможете генерировать серийные номера в вашем
|
||||
приложении. Для нормальной работы генератор должен понимать,
|
||||
к какому продукту Вы собираетесь генерировать серийные номера.
|
||||
Для этого на закладке "Лицензии" VMProtect нажмите кнопку
|
||||
«Экспорт» и в выпадающем списке выберите «Параметры для
|
||||
KeyGen.Net». В текстовом поле ниже появятся несколько строк
|
||||
текста, которые необходимо скопировать и перенести в Ваше
|
||||
приложение в виде строковой константы.</p>
|
||||
|
||||
<p>Пример вызова генератора представлен ниже:</p>
|
||||
<pre>
|
||||
try
|
||||
{
|
||||
string data = @""; // put the exported data here
|
||||
Generator g = new Generator(data);
|
||||
g.UserName = "John Doe";
|
||||
g.EMail = "john@doe.com";
|
||||
g.ExpirationDate = DateTime.Now.AddMonths(1);
|
||||
g.MaxBuildDate = DateTime.Now.AddYears(1);
|
||||
g.RunningTimeLimit = 15;
|
||||
g.HardwareID = "AQIDBAgHBgU=";
|
||||
g.UserData = new byte[] { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
|
||||
string serial = g.Generate();
|
||||
Console.WriteLine("Serial number:\n{0}\n", serial);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("Error: {0}", ex);
|
||||
}
|
||||
|
||||
</pre>
|
||||
|
||||
<p>Строку, скопированную в окне экспорта VMProtect, необходимо
|
||||
поместить в переменную <strong>data</strong>, которая будет
|
||||
передана параметром в конструктор класса генератора серийных
|
||||
номеров. В случае каких-либо проблем с разбором данных продукта,
|
||||
конструктор выбросит исключение с описанием проблемы. Если
|
||||
конструктор отработал успешно, то генератор готов к созданию
|
||||
серийных номеров.</p>
|
||||
|
||||
<p>Серийный номер может содержать различную информацию, которая
|
||||
задается через свойства генератора. Пример выше показывает, как
|
||||
заполнить абсолютно все поля серийного номера. Отдельные поля
|
||||
имеют ограничения. Например, поля <strong>User Name</strong> и
|
||||
<strong>E-Mail</strong> не могут принять строки, которые в
|
||||
кодировке UTF-8 будут иметь длину, превышающую 255 символов. В
|
||||
случае подачи некорректных данных, свойства выбрасывают исключения с
|
||||
описанием проблемы.</p>
|
||||
|
||||
<p>По окончании настройки генератора вызывается метод
|
||||
<strong>Generate()</strong>, который и создает серийный номер. На
|
||||
этом этапе происходит компоновка всех данных номера, подсчет
|
||||
контрольных сумм и, непосредственно, шифрование. В случае, если
|
||||
объем данных превышает максимально допустимую длину, метод выбросит
|
||||
исключение.</p>
|
||||
|
||||
<p>В случае, если необходимо сгенерировать несколько серийных
|
||||
номеров, можно использовать класс генератора несколько раз, не
|
||||
пересоздавая его. Чтобы "очистить" любое из свойств генератора,
|
||||
ему нужно присвоить значение <strong>null</strong>.</p><br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<hr noshade="noshade" size="1" />
|
||||
|
||||
<div align="center">
|
||||
© 2006-2015 Copyright VMProtect Software
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
143
help/ru/manager/keygen/keygen_php.htm
Normal file
143
help/ru/manager/keygen/keygen_php.htm
Normal file
@@ -0,0 +1,143 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<link rel="Stylesheet" type="text/css" href=
|
||||
"../../default.css" />
|
||||
<meta http-equiv="Content-Type" content=
|
||||
"text/html; charset=utf-8" />
|
||||
|
||||
<title>Генератор ключей: UNIX-версия</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>Генераторы ключей: UNIX-версия</h1>
|
||||
|
||||
<h3>Описание</h3>
|
||||
|
||||
<p>UNIX-версия генератора ключей преставляет собой PHP-файл,
|
||||
содержащий все необходимое для генерации серийных номеров. Файл
|
||||
находится в каталоге <strong>Keygen\PHP</strong>, ниже
|
||||
рассмотрены основные моменты его
|
||||
использования.</p>
|
||||
|
||||
<h3>Настройка генератора</h3>
|
||||
|
||||
<p>В самом начале PHP-файла располагается код настройки
|
||||
генератора:</p>
|
||||
<pre class="code">//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// The following lines should be generated by VMProtect License Manager
|
||||
$exported_algorithm = "RSA";
|
||||
$exported_bits = 2048;
|
||||
$exported_private = "PJvj4kEpoQMIpYK+9wEt......xKeiSZgzdiln8Q==";
|
||||
$exported_modulus = "rOlny/3QgZb/VmGr3CmY......I6ESAUmtQ+RBqQ==";
|
||||
$exported_product_code = "oLQdGUn8kVk=";
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
</pre>
|
||||
|
||||
<p>Этот код генерируется автоматически в VMProtect (см. <a href=
|
||||
"../licenses.htm#export">Экспорт параметров продукта</a>) и
|
||||
уникален для каждого конкретного продукта. Очень важно
|
||||
скопировать его без ошибок, в противном случае генератор будет
|
||||
работать некорректно.</p><strong>Содержимое ключа</strong>
|
||||
|
||||
<p>Далее в генераторе задается содержимое серийного номера.
|
||||
Содержимое задается массивом, ниже задаются все возможные
|
||||
параметры ключа, однако в реальных условиях часть из них может
|
||||
отсутствовать:</p>
|
||||
<pre class="code">$params = <strong>array</strong>(
|
||||
user_name => "John Doe", // UTF-8!
|
||||
email => "john@doe.com",
|
||||
hwid => "vHGMdMRvGCPjWcCQ", // Exactly as returned by VMProtectGetCurrentHWID
|
||||
expire_date => <strong>array</strong>(year => 2009, month => 10, day => 1),
|
||||
maxbuild_date => <strong>array</strong>(year => 2009, month => 10, day => 1),
|
||||
time_limit => 10,
|
||||
user_data => <strong>base64_decode</strong>("CGCvRvMWcPHGdMjQ"), // string of bytes
|
||||
);
|
||||
</pre>
|
||||
|
||||
<h3>Функция обработки успешной генерации</h3>
|
||||
|
||||
<p>Ниже расположена простейшая реализация функции, которая
|
||||
вызывается при успешной генерации серийного номера. Единственным
|
||||
параметром она получает строку с номером. Функция должна передать
|
||||
номер вызывающей стороне (регистратору), обычно это делается при
|
||||
помощи команды <strong>echo</strong>. Предварительно строка
|
||||
разбивается на подстроки длиной 75 символов для удобства. Также
|
||||
эта функция может отправлять сгенерированный номер по почте
|
||||
производителю программы или заносить его в базу данных.</p>
|
||||
<pre class="code">function <strong>OnSerialGenerated</strong>($serial)
|
||||
{
|
||||
$serial = <strong>wordwrap</strong>($serial, 75, "\n", true);
|
||||
<strong>echo</strong> $serial;
|
||||
}
|
||||
</pre>
|
||||
|
||||
<h3>Функция обработки ошибок генерации</h3>
|
||||
|
||||
<p>Последний участок кода, требующий внимания - это функция,
|
||||
которая вызывается в случае возникновения проблем. Функция
|
||||
получает в виде параметра строку с текстом ошибки, а после ее
|
||||
завершения вызывается функция <strong>die()</strong>. Функция
|
||||
должна сделать две вещи: вернуть регистратору вместо ключа текст
|
||||
о том, что ключ будет выслан вручную, а также выслать
|
||||
производителю программы всю необходимую информацию для устранения
|
||||
ошибки и ручной генерации ключа.</p>
|
||||
<pre class="code">function <strong>OnSerialGenerationFailed</strong>($details)
|
||||
{
|
||||
<strong>echo</strong> "You will receive serial number in the next 24 hours"; // message to the customer
|
||||
// mail("support@vendor.com", "Houston, we have a problem", $details); // message to vendor
|
||||
}
|
||||
</pre>
|
||||
|
||||
<p>Причин возникновения ошибки может быть несколько: некорректные
|
||||
параметры алгоритма, некорректные параметры ключа, слишком
|
||||
длинное имя пользователя или e-mail. Слишком длинный серийный
|
||||
номер, который не влезает в количество бит, указанное в
|
||||
алгоритме. Поэтому функция
|
||||
<strong>OnSerialGenerationFailed</strong> должна отправить
|
||||
производителю максимально подробную информацию о случившемся,
|
||||
дабы тот мог вручную сгенерировать серийный номер и отправить его
|
||||
покупателю.</p>
|
||||
|
||||
<h3>На что еще следует обратить внимание</h3>
|
||||
|
||||
<p>Генератор ключей в примерах максимально упрощен. Он не
|
||||
учитывает рекомендации по разработке веб-генераторов, данные
|
||||
<a href="index.htm">здесь</a>. Он не проверяет IP-адрес
|
||||
вызывающей стороны и не анализирует входные параметры. Имейте это
|
||||
в виду, когда будете создавать свой собственный генератор на
|
||||
основе этого.</p>
|
||||
|
||||
<p>Имя пользователя и e-mail должны быть переданы в кодировке
|
||||
UTF-8. Уточните у вашего регистратора, в какой кодировке он
|
||||
передает информацию о покупателе и, при необходимости, проведите
|
||||
конвертацию. Неправильная кодировка не приведет к
|
||||
неработоспособности серийного номера, однако номер будет
|
||||
содержать совершенно другое имя пользователя и он может быть
|
||||
удивлен, если вы показываете его, скажем, в окне "О
|
||||
Программе".</p>
|
||||
|
||||
<p>Асимметричное шифрование - достаточно сложный в математическом
|
||||
плане процесс. Если он реализован на чистом PHP, без применения
|
||||
сторонних библиотек, то генерация серийного номера может занять
|
||||
десятки секунд. Генератор использует функции
|
||||
<strong>gmp_powm</strong>, <strong>bi_powmod</strong>,
|
||||
<strong>bcpowod</strong> в случае их наличия. Все эти функции
|
||||
имеют разную скорость. Если генерация ключей на вашем хостинге
|
||||
занимает слишком большое время, рекомендуется пообщаться со
|
||||
службой поддержки на предмет подключения описаных выше функций. К
|
||||
примеру, функция <strong>gmp_powm</strong> работает в десятки раз быстрее
|
||||
функции <strong>bcpowmod</strong>.</p><br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<hr noshade="noshade" size="1" />
|
||||
|
||||
<div align="center">
|
||||
© 2006-2015 Copyright VMProtect Software
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
260
help/ru/manager/keygen/serial_format.htm
Normal file
260
help/ru/manager/keygen/serial_format.htm
Normal file
@@ -0,0 +1,260 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<link rel="Stylesheet" type="text/css" href=
|
||||
"../../default.css" />
|
||||
<meta http-equiv="Content-Type" content=
|
||||
"text/html; charset=utf-8" />
|
||||
|
||||
<title>Формат серийного номера</title>
|
||||
<style type="text/css">
|
||||
/*<![CDATA[*/
|
||||
th {text-align:left;}
|
||||
table {border-collapse:collapse; margin-top: 4px;}
|
||||
td,th {border: 1px solid #B0B0B0; padding-left:10;padding-right:10;}
|
||||
/*]]>*/
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>Формат серийного номера</h1>
|
||||
|
||||
<h3>Структура серийного номера</h3>
|
||||
|
||||
<p>Серийный номер состоит из блоков. Каждый блок
|
||||
начинается с байта идентификатора, который определяет его
|
||||
содержимое и, возможно, длину. Последним всегда идет блок с
|
||||
идентификатором 255, содержащий контрольную сумму всего серийного
|
||||
номера, за исключением последнего блока.</p>
|
||||
|
||||
<p>В зависимости от типа блока, он может иметь фиксированную или
|
||||
переменную длину. Во втором случае обычно длина идет в следующем
|
||||
за идентификатором блока байте. Подробно формат каждого блока
|
||||
описан ниже.</p>
|
||||
|
||||
<h3>Формат блоков</h3>
|
||||
|
||||
<table border="1" cellspacing="0" cellpadding="2">
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
|
||||
<th>Название</th>
|
||||
|
||||
<th>Размер (байт)</th>
|
||||
|
||||
<th>Описание</th>
|
||||
|
||||
<th>Пример</th>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>0x01</td>
|
||||
|
||||
<td>Версия</td>
|
||||
|
||||
<td>1</td>
|
||||
|
||||
<td>Блок содержит версию серийного номера размером в 1 байт.
|
||||
Версия должна быть равна 1.</td>
|
||||
|
||||
<td>01 01</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>0x02</td>
|
||||
|
||||
<td>Имя пользователя</td>
|
||||
|
||||
<td>1 + N</td>
|
||||
|
||||
<td>Блок содержит имя пользователя в кодировке UTF-8. Перед
|
||||
именем пользователя располагается 1 байт длины имени. Таким
|
||||
образом, длина имени пользователя не может превышать 255
|
||||
байт. Завершающий 0 не требуется.</td>
|
||||
|
||||
<td>02 04 4A 5F 48 4E</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>0x03</td>
|
||||
|
||||
<td>E-Mail</td>
|
||||
|
||||
<td>1 + N</td>
|
||||
|
||||
<td>Блок содержит e-mail пользователя в кодировке UTF-8.
|
||||
Перед e-mail'ом располагается 1 байт длины. Таким образом,
|
||||
длина e-mail не может превышать 255 байт. Завершающий 0 не
|
||||
требуется.</td>
|
||||
|
||||
<td>03 07 61 40 62 2E 63 6F 6D</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>0x04</td>
|
||||
|
||||
<td>Идентификатор оборудования</td>
|
||||
|
||||
<td>1 + N</td>
|
||||
|
||||
<td>Блок содержит идентификатор оборудования, возвращенный
|
||||
функцией <strong>VMProtectGetCurrentHWID()</strong>. Функция
|
||||
возвращает строку в кодировке base-64, в серийный номер
|
||||
помещается раскодированный вариант строки. Длина блока данных
|
||||
должна быть кратна 4. Перед блоком данных располагается байт
|
||||
длины. Максимальная длина блока - 32 байта.</td>
|
||||
|
||||
<td>04 08 E1 E2 E3 E4 A1 A2 A3 A4</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>0x05</td>
|
||||
|
||||
<td>Дата окончания лицензии</td>
|
||||
|
||||
<td>4</td>
|
||||
|
||||
<td>Блок содержит дату окончания действия серийного номера.
|
||||
Формат хранения даты описан ниже.</td>
|
||||
|
||||
<td>05 01 0A 07 DA</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>0x06</td>
|
||||
|
||||
<td>Максимальное время работы</td>
|
||||
|
||||
<td>1</td>
|
||||
|
||||
<td>Блок содержит 1 байт с временем работы программы в
|
||||
минутах. Максимальное время работы, таким образом, может
|
||||
составлять 255 минут.</td>
|
||||
|
||||
<td>06 05</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>0x07</td>
|
||||
|
||||
<td>Код продукта</td>
|
||||
|
||||
<td>8</td>
|
||||
|
||||
<td>Блок содержит код продукта - 8 байт, которые создаются
|
||||
VMProtect и выгружаются при экспорте параметров продукта.
|
||||
Выгружаются они в кодировке base-64, перед помещением в
|
||||
серийный номер строку необходимо преобразовать в массив байт.
|
||||
Размер массива должен быть строго равен 8 байтам.
|
||||
<strong>Этот блок является обязательным, без него защищенная
|
||||
программа будет работать некорректно!</strong></td>
|
||||
|
||||
<td>07 01 02 03 04 05 06 07 08</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>0x08</td>
|
||||
|
||||
<td>Данные пользователя</td>
|
||||
|
||||
<td>1 + N</td>
|
||||
|
||||
<td>Блок содержит до 255 байт пользовательских данных.
|
||||
Система лицензирования не анализирует эти данные и возвращает
|
||||
их при вызове функции
|
||||
<strong>VMProtectGetSerialNumberData()</strong>. Перед блоком
|
||||
данных располагается байт, содержащий размер пользовательских
|
||||
данных.</td>
|
||||
|
||||
<td>08 05 01 02 03 04 05</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>0x09</td>
|
||||
|
||||
<td>Максимальная дата сборки</td>
|
||||
|
||||
<td>4</td>
|
||||
|
||||
<td>Блок содержит максимальную дату сборки приложения, с
|
||||
которым будет работать этот серийный номер. Формат хранения
|
||||
даты описан ниже.</td>
|
||||
|
||||
<td>09 01 0A 07 DA</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>0xFF</td>
|
||||
|
||||
<td>Контрольная сумма</td>
|
||||
|
||||
<td>4</td>
|
||||
|
||||
<td>Блок содержит контрольную сумму серийного номера. Блок
|
||||
располагается последним и контрольная сумма считается для
|
||||
всех блоков, идущих перед этим. Подробнее о расчете
|
||||
контрольной суммы написано ниже.</td>
|
||||
|
||||
<td>FF 01 02 03 04</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h3>Формат хранения даты</h3>
|
||||
|
||||
<p>Даты в серийном номере хранятся в виде двойного слова -
|
||||
0xYYYYMMDD. Старшее слово содержит год, а младшее - день и месяц.
|
||||
Байты расположены в порядке Little Endian - от младшего к
|
||||
старшему. В случае, если имеется указатель на первый байт записи,
|
||||
то дата может быть считана и записана следующим кодом:</p>
|
||||
<pre class="code"><strong>byte *</strong>pDate = 0xNNNNNN; // адрес даты
|
||||
<strong>*</strong>(<strong>DWORD *</strong>)pDate = (2010 << 16) | (10 << 8) | 1; // October 1, 2010
|
||||
<strong>DWORD</strong> dwExp = *(<strong>DWORD *</strong>)pDate;
|
||||
</pre>
|
||||
|
||||
<h3>Подсчет контрольной суммы</h3>
|
||||
|
||||
<p>Контрольная сумма серийного номера вычисляется при помощи
|
||||
алгоритма хеширования SHA-1. Результатом работы алгоритма
|
||||
являются пять 32-битных слов. Первое слово используется в
|
||||
качестве контрольной суммы серийного номера. <strong>Обратите
|
||||
внимание:</strong> слово записывается в формате Little Endian (от
|
||||
младшего байта к старшему). В строковом представлении хеша SHA-1
|
||||
используется формат Big Endian - числа записываются от старшего
|
||||
байта к младшему, поэтому если SHA-1 генерируется функцией,
|
||||
которая возвращает строку (как в PHP), то первые четыре байта
|
||||
хеша необходимо предварительно
|
||||
развернуть.</p>
|
||||
|
||||
<h3>Дополнительная информация</h3>
|
||||
|
||||
<p>Блоки с номерами, отличными от описанных выше, игнорируются
|
||||
системой лицензирования. Возможно появление новых блоков в
|
||||
будущих версиях. <strong>Не рекомендуется создавать свои блоки,
|
||||
используя свободные идентификаторы!</strong> Во-первых, это может
|
||||
привести к неработоспособности ключа с новыми версиями системы
|
||||
лицензирования. А во-вторых, защищаемая программа все равно не
|
||||
сможет прочитать значения этих блоков. Для хранения какой-либо
|
||||
информации в ключе нужно использовать поле <strong>User
|
||||
Data</strong>, которое предназначено именно для этого.</p>
|
||||
|
||||
<p>Серийный номер не содержит "соли" (SALT) - случайной
|
||||
информации, предназначенной для того, чтобы ключи для одних и тех
|
||||
же данных получались разными. Эта задача возлагается на алгоритм
|
||||
шифрования. Если необходимы отличия на уровне серийных номеров,
|
||||
скажем для серии ключей, проданных в организацию, можно записать
|
||||
номер ключа строкой в поле имени пользователя (ООО "Компания",
|
||||
ключ 1 из 10) или занести эту информацию в поле <strong>User
|
||||
Data</strong> в любом удобном для разработчика формате.</p><br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<hr noshade="noshade" size="1" />
|
||||
|
||||
<div align="center">
|
||||
© 2006-2015 Copyright VMProtect Software
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
Reference in New Issue
Block a user