- Генерация ключевой пары
- Примеры шаблонов ключей ГОСТ Р 34. 10-2012
- Поддерживаемые механизмы генерации ключей
- Пример генерации ключевой пары ГОСТ Р 34. 10-2012
- Примеры шаблонов ключей ECDSA
- Пример генерации ключевой пары ECDSA
- Установка и смена локального PIN-кода
- Разблокировка PIN-кода Пользователя
- Шифрование и расшифрование
- Шифрование данных
- Пример шифрования данных по алгоритмам ГОСТ 28147-89 и ГОСТ Р 34. 12-2015
- Пример расшифрования данных по алгоритму ГОСТ 28147-89
- Создание объекта на токене
- Импорт объектов на токен
- Поиск объектов на токене
- Чтение и изменение объектов
- Удаление объектов на токене
- Генерация секретного ключа
- Примеры шаблона секретного ключа
- Пример генерации секретного ключа
- Вычисление MAC (Message Authentication Code)
- Пример получения MAC от данных по алгоритму ГОСТ Р 34. 12-2015
Генерация ключевой пары
Устройства Рутокен поддерживают следующие типы ключей асимметричной криптографии (CK_KEY_TYPE) :
- CKK_GOSTR3410 для ключей ГОСТ Р 34.10-2001 и ГОСТ Р 34.10-2012 (256 бит),
- CKK_GOSTR3410_512 для ключей ГОСТ Р 34.10-2012 (512 бит),
- CKK_RSA
- CKK_EC для ключей ECDSA.
Примеры шаблонов ключей ГОСТ Р 34. 10-2012
Ниже представлены примеры шаблонов закрытого и открытого ключа ГОСТ Р 34. 10-2012 с пояснениями.
Поддерживаемые механизмы генерации ключей
Устройства Рутокен поддерживают следующие механизмы генерации ключевой пары:
- CKM_GOSTR3410_KEY_PAIR_GEN для генерации ключевой пары ГОСТ Р 34.10.2001 и ГОСТ Р 34.10.2012 с длиной ключа 256 бит,
- CKM_GOSTR3410_512_KEY_PAIR_GEN для генерации ключевой пары ГОСТ Р 34.10.2012 с длиной ключа 512 бит,
- CKM_RSA_PKCS_KEY_PAIR_GEN для генерации ключевой пары RSA,
- CKM_EC_KEY_PAIR_GEN для генерации ключевой пары ECDSA.
Пример генерации ключевой пары ГОСТ Р 34. 10-2012
Предварительно должна быть открыта сессия чтения/записи с авторизацией с правами пользователя Рутокен.
Примеры шаблонов ключей ECDSA
Ниже представлены примеры шаблонов закрытого и открытого ключа ECDSA ключа
Пример генерации ключевой пары ECDSA
Все параметры форматирования задаются структурой типа CK_RUTOKEN_INIT_PARAM, указатель на которую вместе с PIN-кодом Администратора передаются функции C_EX_InitToken().
При форматировании стандартной функцией C_InitToken() возможно задать только новый PIN-код Администратора и метку токена. После форматирования следует задать PIN-код Пользователя функцией C_InitPIN(), поскольку после форматирования через C_InitToken() его значение остается незаданным.
Установка и смена локального PIN-кода
Помимо двух глобальных ролей Администратора и Пользователя, устройства Рутокен поддерживают до 29 PIN-кодов Локальных Пользователей для разных технических нужд.
Установка или смена локального PIN-кода должна выполняться Пользователем Рутокен и не требует открытой сессии и авторизации – PIN-код Пользователя передается прямо в функцию C_EX_SetLocalPin().
Разблокировка PIN-кода Пользователя
Счетчик автоматически сбрасывается при вводе правильного PIN-кода Пользователя, если не был превышен заданный максимум попыток.
Шифрование и расшифрование
Устройства Рутокен поддерживают следующие механизмы шифрования:
- CKM_GOST28147_ECB для шифрования алгоритмом ГОСТ 28147-89 в режиме простой замены,
- CKM_GOST28147 для шифрования алгоритмом ГОСТ 28147-89 в режиме гаммирования с обратной связью (программное и аппаратное),
- для шифрования алгоритмом Кузнечик в режиме простой замены (ГОСТ 34.13-2018),
- для шифрования алгоритмом Кузнечикв режиме гаммирования CTR с мешингом ACPKM (Р 1323565.1.017-2018),
- для шифрования алгоритмом Магма в режиме простой замены (ГОСТ 34.13-2018),
- для шифрования алгоритмом Магмав режиме гаммирования CTR с мешингом ACPKM (Р 1323565.1.017-2018),
- CKM_RSA_PKCS для шифрования алгоритмом RSA.
Так как в режиме простой замены (механизм CKM_GOST28147_ECB) шифрование каждого блока данных осуществляется одним и тем же ключом, этот механизм должен применяться только для данных небольшого размера (например, ключей). В противном случае стойкость алгоритма снижается.
Для того, чтобы шифрование/расшифрование было выполнено аппаратно самим устройством, ключ должен находиться на токене (то есть атрибут CKA_TOKEN используемого для шифрования ключа должен быть равен значению TRUE). Если атрибут CKA_TOKEN ключа, который используется для шифрования/расшифрования, равен FALSE, то операция будет выполняться программно.
Шифрование данных
Для шифрования данных одним блоком служат функции C_EncryptInit() и C_Encrypt(), для поточного – С_EncryptInit(), C_EncryptUpdate() и C_EncryptFinal().
Сначала операцию шифрования нужно инициализировать вызовом функции C_EncryptInit(), передав в нее идентификатор сессии, механизма и секретного ключа. В параметрах механизмов для ГОСТ 28147-89 и ГОСТ Р 34. 12-2015 можно задать вектор инициализации и его длину.
Далее шифрование можно выполнить для всего блока данных целиком, вызвав функцию C_Encrypt(), или по частям, вызывая C_EncryptUpdate() для каждого непоследнего блока и C_EncryptFinal() для завершающего блока. Если в C_EncryptFinal() передать пустой блок данных, то функция вернет суммарный размер всех блоков зашифрованных данных.
Пример шифрования данных по алгоритмам ГОСТ 28147-89 и ГОСТ Р 34. 12-2015
Для расшифрования данных служат функции C_DecryptInit() и C_Decrypt() для любого режима шифрования.
Сначала операцию расшифрования нужно инициализировать вызовом функции C_DecryptInit(), передав в нее идентификатор сессии, механизма и секретного ключа. В параметрах механизма для ГОСТ 28147-89 можно задать вектор инициализации и его длину.
Далее расшифрование выполняется вызовом функции C_Decrypt() с передачей в нее зашифрованные данные. Размер расшифрованных данных можно узнать, вызвав C_Decrypt() с пустым указателем вместо указателя на буфера для расшифрованных данных.
Пример расшифрования данных по алгоритму ГОСТ 28147-89
Стандарт PKCS#11 различает несколько классов объектов. Объекты содержат набор атрибутов, каждый из которых имеет только одно определенное значение.
Атрибут CKA_TOKEN определяет, будет ли созданный объект храниться только в рамках текущей сессии (значение CK_FALSE), или будет сохранен в памяти Рутокен (значение CK_TRUE). Сессионный объект будет уничтожен автоматически при закрытии сессии, а сохраненный на токене доступен вплоть до физического удаления объекта.
Атрибут CKA_PRIVATE определяет доступность объекта. Пользователь не имеет доступа к приватному объекту (значение CK_TRUE) до тех пор, пока не выполнит аутентификацию на токене. Публичный же объект доступен без аутентификации (значение CK_FALSE).
Атрибут CKA_MODIFIABLE отвечает за возможность изменения атрибутов объекта после его создания. По умолчанию атрибут принимает значение CK_TRUE, при котором редактирование атрибутов объекта становится возможным. Значение CK_FALSE означает, что созданный объект будет доступен «только для чтения» и значения атрибутов объекта после его создания не могут быть изменены.
Сгенерированные устройствами Рутокен закрытые и секретные ключевые объекты в целях безопасности является неизвлекаемыми. Это означает, что значение ключа (значение атрибута CKA_VALUE) невозможно получить через функцию C_GetAttributeValue(). Все криптографические операции с такими ключами производятся внутри устройства без передачи значения ключа наружу.
Создание объекта на токене
Для создания объектов на токене предназначена функция C_CreateObject(). В нее передается предварительно созданный шаблон с атрибутами создаваемого объекта, размер шаблона и хэндл открытой сессии с правами Пользователя. Функция возвращает хэндл созданного с указанными атрибутами объекта.
Устройства Рутокен, сертифицированные ФСБ, не поддерживают создание (импорт) ключей функцией C_CreateObject по алгоритмам ГОСТ 28147-89, ГОСТ Р 34. 10-2001 и ГОСТ Р 34. 10-2012 в долговременную память (с флагом CKA_TOKEN = TRUE).
Импорт объектов на токен
Для импорта объектов также используется функция C_CreateObject(). В нее передается предварительно созданный шаблон с атрибутами импортируемого объекта (в том числе и значением CKA_VALUE), размер шаблона и хэндл открытой сессии с правами Пользователя. Функция возвращает хэндл созданного с указанными атрибутами объекта.
Поиск объектов на токене
Для поиска объектов на токене предназначены три функции C_FindObjectsInit(), C_FindObjects() и C_FindObjectsFinal(). Сначала операция поиска инициализируется функцией C_FindObjectsInit(), в которую передается указатель шаблон атрибутов для поиска объекта и его размер, затем функция C_FindObjects() выполняет поиск объектов согласно заданным атрибутам и возвращает хэндлы всех найденных объектов в массиве. C_FindObjectsFinal() завершает процедуру поиска.
Чтение и изменение объектов
Для чтения атрибутов созданного объекта используется функция C_GetAttributeValue(). Если объекты или его атрибуты не являются защищенными от записи (например, значение атрибута CKA_MODIFIABLE равно CK_TRUE), то значения атрибутов могут быть изменены функцией C_SetAttributeValue().
Сгенерированные устройствами Рутокен закрытые и секретные ключевые объекты в целях безопасности является неизвлекаемыми. Это означает, что значение ключа (значение атрибута CKA_VALUE) невозможно получить через функцию C_GetAttributeValue(). Все криптографические операции с такими ключами производятся внутри устройства без извлечения ключа и передачи его значения наружу.
Удаление объектов на токене
Для удаления объекта на токене необходимо знать его хэндл, который следует передать в функцию C_DestroyObject() (предварительно должна быть открыта сессия с правами Пользователя). Если хэндл объекта неизвестен, то по любому известному атрибуту объекта можно получить его хэндл через группу функций C_FindObjectsInit(), C_FindObjects() и C_FindObjectsFinal().
Генерация секретного ключа
Все поддерживаемые устройствами Рутокен атрибуты объектов представлены в разделе Объекты секретных ключей.
Устройства Рутокен поддерживают следующие типы секретных ключей (CK_KEY_TYPE) :
- CKK_GENERIC_SECRET для абстрактных ключей произвольной длины,
- CKK_GOST28147 для ключей ГОСТ 28147-89,
- для использования в алгоритмах шифрования ГОСТ 34.12-2018 (ГОСТ Р 34.12-2015) с длиной блока 64 бит,
- CKK_KUZNECHIK для использования в алгоритмах шифрования ГОСТ 34.12-2018 (ГОСТ Р 34.12-2015) с длиной блока 128 бит,
- CKK_MAGMA_TWIN_KEY для использования в алгоритме экспорта и импорта ключей Р 1323565.1.017-2018, построенном на основании блочного шифра «Магма»,
- CKK_KUZNECHIK_TWIN_KEY для использования в алгоритме экспорта и импорта ключей Р 1323565.1.017-2018, построенном на основании блочного шифра «Кузнечик»,
Примеры шаблона секретного ключа
Устройства Рутокен поддерживают следующие механизмы генерации секретного ключа:
- CKM_GOST28147_KEY_GEN для генерации секретного ключа ГОСТ 28147-89 (библиотекой rtPKCS11ECP),
- CKM_GOST_KEY_GEN для генерации секретного ключа ГОСТ 28147-89 (библиотекой rtPKCS11).
- CKM_KUZNECHIK_KEY_GEN для генерации секретного ключа ГОСТ 34.12-2018 (ГОСТ Р 34.12-2015), используемого в алгоритмах шифрования с длиной блока 64 бит.
- CKM_MAGMA_KEY_GEN для генерации секретного ключа ГОСТ 34.12-2018 (ГОСТ Р 34.12-2015), используемого в алгоритмах шифрования с длиной блока 128 бит.
Пример генерации секретного ключа
Для генерации секретного ключа предназначена функция C_GenerateKey(), в которую передается механизм генерации и шаблон ключа.
Предварительно должна быть открыта сессия чтения/записи с авторизацией с правами Пользователя.
Вычисление MAC (Message Authentication Code)
Устройства Рутокен поддерживает создание MAC на ключах типа CKK_KUZNECHIK, CKK_MAGMA и CKK_GOST28147. Объекты ключей, на которых вычисляется и проверяется MAC, также должны иметь атрибуты CKA_SIGN и CKA_VERIFY установленные в CK_TRUE.
Для вычисления MAC служат функции C_SignInit() и C_Sign(). Сначала операцию получения MAC нужно инициализировать через C_SignInit(), передав в нее идентификатор сессии и ссылку на механизм. Размер буфера под MAC можно определить, вызвав C_Sign() с нулевым указателем на выходные данные. Вызвав C_Sign() с не нулевым указателем на выходные данные мы получим вычисленный MAC.
Предварительно должна быть открыта сессия чтения/записи.
Пример получения MAC от данных по алгоритму ГОСТ Р 34. 12-2015
Для проверки MAC служат функции C_VerifyInit() и C_Verify(). Сначала операцию проверки MAC нужно инициализировать через C_VerifyInit(), передав в нее идентификатор сессии и ссылку на механизм. Проверка MAC происходит при вызове функции C_Verify() с переданным указателем на данные и MAC.