Токены PKCS#11: генерация ключевой пары и неизвлекаемость приватного ключа (Продолжение)

Токены PKCS#11: генерация ключевой пары и неизвлекаемость приватного ключа (Продолжение)

В предыдущей статье «Токены PKCS#11: сертификаты и закрытые ключи » мы рассмотрели как можно однозначно связать тройку Сертификат x ПубличныйКлюч x ПриватныйКлюч , хранимую на токене/смаркарте с интерфейсом PKCS#11 v.2.40. В данной статье мы поговорим о генерации ключевой пары. Опираться мы будем, как и прошлый раз, на «ГОСТ Р 34.10-2012 Информационная технология. Криптографическая защита информации. Процессы формирования и проверки электронной цифровой подписи» .

Итак, что такое ключевая пара?

Ключевая пара включает в себя два ключа:

    Закрытый ключ/Приватный /Private key — ключ, известный только своему владельцу. Только сохранение владельцем/пользователем в тайне своего закрытого ключа гарантирует невозможность подделки злоумышленником документа и цифровой подписи от имени заверяющего;

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

  1. id-GostR3410-2001-CryptoPro-A-ParamSet;
  2. id-GostR3410-2001-CryptoPro-B-ParamSet;
  3. id-GostR3410-2001-CryptoPro-C-ParamSet;
  4. id-GostR3410-2001-CryptoPro-XchA-ParamSet;
  5. id-GostR3410-2001-CryptoPro-XchB-ParamSet.
  1. id-tc26-gost-3410-2012-512-paramSetA;
  2. id-tc26-gost-3410-2012-512-paramSetB.

И именно оно определяет длину закрытого/открытого ключей и корректность закрытого ключа:

— длина закрытого ключа 256 бит;

— длина закрытого ключа 512 бит. И так, открытый ключ получается из закрытого ключа.

А откуда берется закрытый ключ?

Для получения закрытого ключа сначала необходимо решить какой длины будет закрытый ключ (256 или 512 бит), затем определиться с криптопараметрами ключевой пары. Теперь берем датчик случайных чисел и получаем случайное число соответствующей длины. Собственно это случайное число и должно стать значением d закрытого ключа (ключом подписи d). Это значение должно удовлетворять следующему правилу:

0 < d < q, где q – простое число из криптопараметров.

Что делать, если это условие не выполняется? Если d == 0, то просто сгенерировать новое случайное число. В противном случае достаточно бывает взять остаток от деления на цело значения d, которое превышает q, на q (d % q). Остаток и станет значением закрытого ключа.

Именно поэтому регулятор (ФСБ России) предъявляет особые требования к датчику случайных чисел.

В качестве примера основного источника для заполнения буфера:

  • случайными цифрами можно привести:
  • регистр TSC процессора – счетчик тактов процессора;
  • счетчик времени GTC;
  • автоинкрементируемый счетчик в отдельном потоке;
  • стандартная функция rand();
  • координаты мыши.
  • Счетчик времени работы процесса в пользовательском режиме;
  • Таймер высокого разрешения Windows.

Для генерации ключевой пары используется фунция C_GenerateKeyPair. В зависимости от того, какую ключевую пару (с какой длиной закрытого ключа 256 или 512 бит) мы генерируем, в ней будет использоваться соответствующий механизм:

  • CKM_GOSTR3410_KEY_PAIR_GEN для ключевой пары с закрытым ключом в 256 бит;
  • CKM_GOSTR3410_512_KEY_PAIR_GEN для ключевой пары с закрытым ключом в 512 бит.
Нас интересуют атрибуты извлекаемости закрытого ключа.

Это прежде атрибут CKA_SENSITIVE, отвечающий за возможность получения значения закрытого ключа. Если значение атрибута CKA_SENSITIVE установлено в CK_TRUE, то закрытый ключ не может быть извлечен из токена в открытом виде. Второй атрибут CKA_EXTRACTABLE позволяет получать закрытый ключ в зашифрованном виде. Для этого его необходимо установить CK_TRUE.

Установка атрибута CKA_SENSITIVE в CK_TRUE, а атрибута CKA_EXTRACTABLE в CK_FALSE при генерации ключевой пары делает закрытый ключ абсолютно неизвлекаемым. Возможность определять является ли ключ экспортабельным имеется в браузере Redfox:

Кто-то скажет, — а что если изменить значения этих атрибутов. Как правило этого сделать нельзя, защиту понизить нельзя, также как «нельзя понижать градус». Точно также можно сделать неизвлекаемым закрытый ключ после его импорта на токен (если конечно токен/смарткарта разрешают импорт). После создания (или во время создания) объекта CKO_PRIVATE_KEY необходимо установить CKA_SENSITIVE=CK_TRUE, а атрибута CKA_EXTRACTABLE=CK_FALSE.

В последнем случае (при импорте) следует иметь в виду, что хотя закрытый ключ и стал неизвлекаемым, он появился со стороны (например, из PKCS#12), и гарантии, что нет еще где-то его дубликата нету.

И вот здесь не мешало бы напомнить тебе, уважаемый читатель, что безопасность обеспечивается только КОМПЛЕКСОМ организационных и технических мероприятий . Поэтому не получится латать дыры в организационной безопасности за счет технических средств и наоборот — все должно быть органично согласовано. В том числе, и при доступе к значению закрытого ключа.

Убедиться, что на токен/смарткарте находятся полноценные объекты PKCS#11 (CKO_PRIVATE_KEY, CKO_PUBLIC_KEY, CKO_CERTIFICATE), которые участвуют в криптографических операциях на самом токене удобно с помощью доступной для свободного скачивания утилиты p11conf:

Для того, чтобы посмотреть какие объекты находятся на токене достаточно выполнить команду вида:

Если такие объекты отсутствуют на токене, а говорят, что используется токен PKCS#11 с неизвлекаемым ключом, то это скорей всего не так. Скорей всего токен используется просто как флэшка с PIN-кодом, а сертификат и ключи хранятся как объекты CKO_DATA.

И наконец, для того, чтобы посмотреть не только какие типы объектов хранятся на токене, а объекты со всеми атрибутами необходимо использовать дополнительно флаг –d:

Все сказанное здесь справедливо для токена/смарткарты с интерфейсом PKCS#11, включая облачный токен.

В заключение напомним, что токены/смаркарты с интерфейсом PKCS#11 широко используются в проектах Mozilla (браузеры, почтовые клиенты), в браузерах Chrome от Google и других проектах. Если говорить о России, то токены/смаркарты с интерфейсом PKCS#11успешно используются для доступа на портал Госуслуг.

📎📎📎📎📎📎📎📎📎📎