VMProtect/help/ru/manager/keygen/serial_format.htm

261 lines
11 KiB
HTML
Raw Normal View History

2023-05-14 16:21:09 +03:00
<!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 &lt;&lt; 16) | (10 &lt;&lt; 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>