...
Открытие и закрытие сессии
// Про колбэк
Code Block | ||||
---|---|---|---|---|
| ||||
CK_SESSION_HANDLE hSession = NULL_PTR; // Хэндл открытой сессии ... /* Открыть RW сессию в первом доступном слоте */ printf("Opening Session"); rv = pFunctionList->C_OpenSession(aSlots[0], // Идентификатор слота CKF_SERIAL_SESSION | CKF_RW_SESSION, // Флаги сессии NULL_PTR, NULL_PTR, &hSession); // Хэндл сессии if (rv != CKR_OK) printf(" -> Failed\n"); else printf(" -> OK\n"); ... /* Закрыть все открытые сессии в слоте */ printf("C_CloseAllSession"); rv = pFunctionList->C_CloseAllSessions(aSlots[0]); if (rvTemp != CKR_OK) printf(" -> Failed\n"); else printf(" -> OK\n"); hSession = NULL_PTR; |
...
Code Block | ||||
---|---|---|---|---|
| ||||
<!PINPADFILE RU> // обязательный признак строки, которая будет распознаваться Rutoken PINPad <!>some text // текст, нераспознаваемый Rutoken PINPad <N>some text // наименование поля <V>some text // значение поля |
Пример отформатированных данных для Рутокен PINPad
Code Block | ||||
---|---|---|---|---|
| ||||
ФИО: Петров Петр Петрович Москва, Пионерская ул, д. 3, кв. 72 Перевод со счета : 42301810001000075212 Сумма : 150000 Валюта : RUR Наименование получателя : Иванова Елена Ивановна Номер счета получателя : 40817810338295201618 БИК банка получателя : 044525225 Наименование банка получателя : ОАО 'СБЕРБАНК РОССИИ' Г. МОСКВА Номер счета банка получателя : 30101810400000000225 Назначение платежа : перевод личных средств |
Code Block | ||||
---|---|---|---|---|
| ||||
<!PINPADFILE RU> <!>невидимый текст <N>ФИО:<V>Петров Петр Петрович Москва, Пионерская ул, д. 3, кв. 72 <N>Перевод со счета:<V>42301810001000075212 <N>Сумма:<V>150000 <N>Валюта:<V>RUR <N>Наименование получателя:<V>Иванова Елена Ивановна <N>Номер счета получателя:<V>40817810338295201618 <N>БИК банка получателя:<V>044525225 <N>Наименование банка получателя:<V>ОАО 'СБЕРБАНК РОССИИ' Г. МОСКВА <N>Номер счета банка получателя:<V>30101810400000000225 <N>Назначение платежа:<V>перевод личных средств |
Чтобы данные были корректно распознаны Рутокен PINPad, они быть представлены в виде ANSI строки с однобайтовыми символами, соответствующими кодировке CP-1251.
Code Block | ||||
---|---|---|---|---|
| ||||
char szPINPadMessage[] = "<!PINPADFILE RU><!>невидимый текст<N>ФИО:<V>Петров Петр Петрович Москва, Пионерская ул, д. 3, кв. 72<N>Перевод со счета:<V>42301810001000075212<N>Сумма:<V>150000<N>Валюта:<V>RUR<N>Наименование получателя:<V>Иванова Елена Ивановна<N>Номер счета получателя:<V>40817810338295201618<N>БИК банка получателя:<V>044525225<N>Наименование банка получателя:<V>ОАО 'СБЕРБАНК РОССИИ' Г. МОСКВА<N>Номер счета банка получателя:<V>30101810400000000225<N>Назначение платежа:<V>перевод личных средств"; |
Eсли файл с исходным кодом сохранен в UTF-8 и на текущей машине не установлена кодировка CP-1251 для не-UNICODE программ, данные можно представить в виде двоичной строки с кодами символов в ANSI:
Code Block | ||||
---|---|---|---|---|
| ||||
char szPINPadMessageTrueCP1251[] = { 0x3C, 0x21, 0x50, 0x49, 0x4E, 0x50, 0x41, 0x44, 0x46, 0x49, 0x4C, 0x45, 0x20, 0x52, 0x55, 0x3E, 0x3C, 0x21, 0x3E, 0xED, 0xE5, 0xE2, 0xE8, 0xE4, 0xE8, 0xEC, 0xFB, 0xE9, 0x20, 0xF2, 0xE5, 0xEA, 0xF1, 0xF2, 0x3C, 0x4E, 0x3E, 0xD4, 0xC8, 0xCE, 0x3A, 0x3C, 0x56, 0x3E, 0xCF, 0xE5, 0xF2, 0xF0, 0xEE, 0xE2, 0x20, 0xCF, 0xE5, 0xF2, 0xF0, 0x20, 0xCF, 0xE5, 0xF2, 0xF0, 0xEE, 0xE2, 0xE8, 0xF7, 0x20, 0xCC, 0xEE, 0xF1, 0xEA, 0xE2, 0xE0, 0x2C, 0x20, 0xCF, 0xE8, 0xEE, 0xED, 0xE5, 0xF0, 0xF1, 0xEA, 0xE0, 0xFF, 0x20, 0xF3, 0xEB, 0x2C, 0x20, 0xE4, 0x2E, 0x20, 0x33, 0x2C, 0x20, 0xEA, 0xE2, 0x2E, 0x20, 0x37, 0x32, 0x3C, 0x4E, 0x3E, 0xCF, 0xE5, 0xF0, 0xE5, 0xE2, 0xEE, 0xE4, 0x20, 0xF1, 0xEE, 0x20, 0xF1, 0xF7, 0xE5, 0xF2, 0xE0, 0x3A, 0x3C, 0x56, 0x3E, 0x34, 0x32, 0x33, 0x30, 0x31, 0x38, 0x31, 0x30, 0x30, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x37, 0x35, 0x32, 0x31, 0x32, 0x3C, 0x4E, 0x3E, 0xD1, 0xF3, 0xEC, 0xEC, 0xE0, 0x3A, 0x3C, 0x56, 0x3E, 0x31, 0x35, 0x30, 0x30, 0x30, 0x30, 0x3C, 0x4E, 0x3E, 0xC2, 0xE0, 0xEB, 0xFE, 0xF2, 0xE0, 0x3A, 0x3C, 0x56, 0x3E, 0x52, 0x55, 0x52, 0x3C, 0x4E, 0x3E, 0xCD, 0xE0, 0xE8, 0xEC, 0xE5, 0xED, 0xEE, 0xE2, 0xE0, 0xED, 0xE8, 0xE5, 0x20, 0xEF, 0xEE, 0xEB, 0xF3, 0xF7, 0xE0, 0xF2, 0xE5, 0xEB, 0xFF, 0x3A, 0x3C, 0x56, 0x3E, 0xC8, 0xE2, 0xE0, 0xED, 0xEE, 0xE2, 0xE0, 0x20, 0xC5, 0xEB, 0xE5, 0xED, 0xE0, 0x20, 0xC8, 0xE2, 0xE0, 0xED, 0xEE, 0xE2, 0xED, 0xE0, 0x3C, 0x4E, 0x3E, 0xCD, 0xEE, 0xEC, 0xE5, 0xF0, 0x20, 0xF1, 0xF7, 0xE5, 0xF2, 0xE0, 0x20, 0xEF, 0xEE, 0xEB, 0xF3, 0xF7, 0xE0, 0xF2, 0xE5, 0xEB, 0xFF, 0x3A, 0x3C, 0x56, 0x3E, 0x34, 0x30, 0x38, 0x31, 0x37, 0x38, 0x31, 0x30, 0x33, 0x33, 0x38, 0x32, 0x39, 0x35, 0x32, 0x30, 0x31, 0x36, 0x31, 0x38, 0x3C, 0x4E, 0x3E, 0xC1, 0xC8, 0xCA, 0x20, 0xE1, 0xE0, 0xED, 0xEA, 0xE0, 0x20, 0xEF, 0xEE, 0xEB, 0xF3, 0xF7, 0xE0, 0xF2, 0xE5, 0xEB, 0xFF, 0x3A, 0x3C, 0x56, 0x3E, 0x30, 0x34, 0x34, 0x35, 0x32, 0x35, 0x32, 0x32, 0x35, 0x3C, 0x4E, 0x3E, 0xCD, 0xE0, 0xE8, 0xEC, 0xE5, 0xED, 0xEE, 0xE2, 0xE0, 0xED, 0xE8, 0xE5, 0x20, 0xE1, 0xE0, 0xED, 0xEA, 0xE0, 0x20, 0xEF, 0xEE, 0xEB, 0xF3, 0xF7, 0xE0, 0xF2, 0xE5, 0xEB, 0xFF, 0x3A, 0x3C, 0x56, 0x3E, 0xCE, 0xC0, 0xCE, 0x20, 0x27, 0xD1, 0xC1, 0xC5, 0xD0, 0xC1, 0xC0, 0xCD, 0xCA, 0x20, 0xD0, 0xCE, 0xD1, 0xD1, 0xC8, 0xC8, 0x27, 0x20, 0xC3, 0x2E, 0x20, 0xCC, 0xCE, 0xD1, 0xCA, 0xC2, 0xC0, 0x3C, 0x4E, 0x3E, 0xCD, 0xEE, 0xEC, 0xE5, 0xF0, 0x20, 0xF1, 0xF7, 0xE5, 0xF2, 0xE0, 0x20, 0xE1, 0xE0, 0xED, 0xEA, 0xE0, 0x20, 0xEF, 0xEE, 0xEB, 0xF3, 0xF7, 0xE0, 0xF2, 0xE5, 0xEB, 0xFF, 0x3A, 0x3C, 0x56, 0x3E, 0x33, 0x30, 0x31, 0x30, 0x31, 0x38, 0x31, 0x30, 0x34, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x32, 0x32, 0x35, 0x3C, 0x4E, 0x3E, 0xCD, 0xE0, 0xE7, 0xED, 0xE0, 0xF7, 0xE5, 0xED, 0xE8, 0xE5, 0x20, 0xEF, 0xEB, 0xE0, 0xF2, 0xE5, 0xE6, 0xE0, 0x3A, 0x3C, 0x56, 0x3E, 0xEF, 0xE5, 0xF0, 0xE5, 0xE2, 0xEE, 0xE4, 0x20, 0xEB, 0xE8, 0xF7, 0xED, 0xFB, 0xF5, 0x20, 0xF1, 0xF0, 0xE5, 0xE4, 0xF1, 0xF2, 0xE2 }; |
Пример отформатированных данных для Рутокен PINPad
Code Block | ||||
---|---|---|---|---|
| ||||
ФИО: Петров Петр Петрович Москва, Пионерская ул, д. 3, кв. 72
Перевод со счета : 42301810001000075212
Сумма : 150000
Валюта : RUR
Наименование получателя : Иванова Елена Ивановна
Номер счета получателя : 40817810338295201618
БИК банка получателя : 044525225
Наименование банка получателя : ОАО 'СБЕРБАНК РОССИИ' Г. МОСКВА
Номер счета банка получателя : 30101810400000000225
Назначение платежа : перевод личных средств |
Code Block | ||||
---|---|---|---|---|
| ||||
<!PINPADFILE RU>
<!>невидимый текст
<N>ФИО:<V>Петров Петр Петрович Москва, Пионерская ул, д. 3, кв. 72
<N>Перевод со счета:<V>42301810001000075212
<N>Сумма:<V>150000
<N>Валюта:<V>RUR
<N>Наименование получателя:<V>Иванова Елена Ивановна
<N>Номер счета получателя:<V>40817810338295201618
<N>БИК банка получателя:<V>044525225
<N>Наименование банка получателя:<V>ОАО 'СБЕРБАНК РОССИИ' Г. МОСКВА
<N>Номер счета банка получателя:<V>30101810400000000225
<N>Назначение платежа:<V>перевод личных средств |
Code Block | ||||
---|---|---|---|---|
| ||||
char szPINPadMessage[] = "<!PINPADFILE RU><!>невидимый текст<N>ФИО:<V>Петров Петр Петрович Москва, Пионерская ул, д. 3, кв. 72<N>Перевод со счета:<V>42301810001000075212<N>Сумма:<V>150000<N>Валюта:<V>RUR<N>Наименование получателя:<V>Иванова Елена Ивановна<N>Номер счета получателя:<V>40817810338295201618<N>БИК банка получателя:<V>044525225<N>Наименование банка получателя:<V>ОАО 'СБЕРБАНК РОССИИ' Г. МОСКВА<N>Номер счета банка получателя:<V>30101810400000000225<N>Назначение платежа:<V>перевод личных средств"; |
Если файл с исходным кодом сохранен в UTF-8 и на текущей машине не установлена кодировка CP-1251 для не-UNICODE программ, данные можно представить в виде двоичной строки с кодами символов в ANSI:
Code Block | ||||
---|---|---|---|---|
| ||||
char szPINPadMessageTrueCP1251[] = { 0x3C, 0x21, 0x50, 0x49, 0x4E, 0x50, 0x41, 0x44, 0x46, 0x49, 0x4C, 0x45, 0x20, 0x52, 0x55, 0x3E,
0x3C, 0x21, 0x3E, 0xED, 0xE5, 0xE2, 0xE8, 0xE4, 0xE8, 0xEC, 0xFB, 0xE9, 0x20, 0xF2, 0xE5, 0xEA,
0xF1, 0xF2, 0x3C, 0x4E, 0x3E, 0xD4, 0xC8, 0xCE, 0x3A, 0x3C, 0x56, 0x3E, 0xCF, 0xE5, 0xF2, 0xF0,
0xEE, 0xE2, 0x20, 0xCF, 0xE5, 0xF2, 0xF0, 0x20, 0xCF, 0xE5, 0xF2, 0xF0, 0xEE, 0xE2, 0xE8, 0xF7,
0x20, 0xCC, 0xEE, 0xF1, 0xEA, 0xE2, 0xE0, 0x2C, 0x20, 0xCF, 0xE8, 0xEE, 0xED, 0xE5, 0xF0, 0xF1,
0xEA, 0xE0, 0xFF, 0x20, 0xF3, 0xEB, 0x2C, 0x20, 0xE4, 0x2E, 0x20, 0x33, 0x2C, 0x20, 0xEA, 0xE2,
0x2E, 0x20, 0x37, 0x32, 0x3C, 0x4E, 0x3E, 0xCF, 0xE5, 0xF0, 0xE5, 0xE2, 0xEE, 0xE4, 0x20, 0xF1,
0xEE, 0x20, 0xF1, 0xF7, 0xE5, 0xF2, 0xE0, 0x3A, 0x3C, 0x56, 0x3E, 0x34, 0x32, 0x33, 0x30, 0x31,
0x38, 0x31, 0x30, 0x30, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x37, 0x35, 0x32, 0x31, 0x32, 0x3C,
0x4E, 0x3E, 0xD1, 0xF3, 0xEC, 0xEC, 0xE0, 0x3A, 0x3C, 0x56, 0x3E, 0x31, 0x35, 0x30, 0x30, 0x30,
0x30, 0x3C, 0x4E, 0x3E, 0xC2, 0xE0, 0xEB, 0xFE, 0xF2, 0xE0, 0x3A, 0x3C, 0x56, 0x3E, 0x52, 0x55,
0x52, 0x3C, 0x4E, 0x3E, 0xCD, 0xE0, 0xE8, 0xEC, 0xE5, 0xED, 0xEE, 0xE2, 0xE0, 0xED, 0xE8, 0xE5,
0x20, 0xEF, 0xEE, 0xEB, 0xF3, 0xF7, 0xE0, 0xF2, 0xE5, 0xEB, 0xFF, 0x3A, 0x3C, 0x56, 0x3E, 0xC8,
0xE2, 0xE0, 0xED, 0xEE, 0xE2, 0xE0, 0x20, 0xC5, 0xEB, 0xE5, 0xED, 0xE0, 0x20, 0xC8, 0xE2, 0xE0,
0xED, 0xEE, 0xE2, 0xED, 0xE0, 0x3C, 0x4E, 0x3E, 0xCD, 0xEE, 0xEC, 0xE5, 0xF0, 0x20, 0xF1, 0xF7,
0xE5, 0xF2, 0xE0, 0x20, 0xEF, 0xEE, 0xEB, 0xF3, 0xF7, 0xE0, 0xF2, 0xE5, 0xEB, 0xFF, 0x3A, 0x3C,
0x56, 0x3E, 0x34, 0x30, 0x38, 0x31, 0x37, 0x38, 0x31, 0x30, 0x33, 0x33, 0x38, 0x32, 0x39, 0x35,
0x32, 0x30, 0x31, 0x36, 0x31, 0x38, 0x3C, 0x4E, 0x3E, 0xC1, 0xC8, 0xCA, 0x20, 0xE1, 0xE0, 0xED,
0xEA, 0xE0, 0x20, 0xEF, 0xEE, 0xEB, 0xF3, 0xF7, 0xE0, 0xF2, 0xE5, 0xEB, 0xFF, 0x3A, 0x3C, 0x56,
0x3E, 0x30, 0x34, 0x34, 0x35, 0x32, 0x35, 0x32, 0x32, 0x35, 0x3C, 0x4E, 0x3E, 0xCD, 0xE0, 0xE8,
0xEC, 0xE5, 0xED, 0xEE, 0xE2, 0xE0, 0xED, 0xE8, 0xE5, 0x20, 0xE1, 0xE0, 0xED, 0xEA, 0xE0, 0x20,
0xEF, 0xEE, 0xEB, 0xF3, 0xF7, 0xE0, 0xF2, 0xE5, 0xEB, 0xFF, 0x3A, 0x3C, 0x56, 0x3E, 0xCE, 0xC0,
0xCE, 0x20, 0x27, 0xD1, 0xC1, 0xC5, 0xD0, 0xC1, 0xC0, 0xCD, 0xCA, 0x20, 0xD0, 0xCE, 0xD1, 0xD1,
0xC8, 0xC8, 0x27, 0x20, 0xC3, 0x2E, 0x20, 0xCC, 0xCE, 0xD1, 0xCA, 0xC2, 0xC0, 0x3C, 0x4E, 0x3E,
0xCD, 0xEE, 0xEC, 0xE5, 0xF0, 0x20, 0xF1, 0xF7, 0xE5, 0xF2, 0xE0, 0x20, 0xE1, 0xE0, 0xED, 0xEA,
0xE0, 0x20, 0xEF, 0xEE, 0xEB, 0xF3, 0xF7, 0xE0, 0xF2, 0xE5, 0xEB, 0xFF, 0x3A, 0x3C, 0x56, 0x3E,
0x33, 0x30, 0x31, 0x30, 0x31, 0x38, 0x31, 0x30, 0x34, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
0x30, 0x32, 0x32, 0x35, 0x3C, 0x4E, 0x3E, 0xCD, 0xE0, 0xE7, 0xED, 0xE0, 0xF7, 0xE5, 0xED, 0xE8,
0xE5, 0x20, 0xEF, 0xEB, 0xE0, 0xF2, 0xE5, 0xE6, 0xE0, 0x3A, 0x3C, 0x56, 0x3E, 0xEF, 0xE5, 0xF0,
0xE5, 0xE2, 0xEE, 0xE4, 0x20, 0xEB, 0xE8, 0xF7, 0xED, 0xFB, 0xF5, 0x20, 0xF1, 0xF0, 0xE5, 0xE4,
0xF1, 0xF2, 0xE2 }; |
Подпись данных
Подпись данных
Для вычисления отделяемой подписи сообщения служат функции C_SignInit()
и C_Sign()
Для вычисления отделяемой подписи сообщения служат функции C_SignInit()
и C_Sign()
. Сначала операцию подписи нужно инициализировать через C_SignInit()
, передав в нее идентификатор сессии, механизма и закрытого ключа. Затем размер буфера подписанных данных можно определить, вызвав C_Sign()
, и подписать данные, вызвав C_Sign()
второй раз.
...
Подпись на Рутокен PINPad совместным механизмом хеширования и подписи
При использовании совместного механизма хеширования и подписи в функцию C_Sign()
с совместным механизмом (например, CKM_GOSTR3410_WITH_GOSTR3411
) передается текст в специальным формате для отображения его на экране Рутокен PINPad.
При вызове функции C_Sign()
на экране Рутокен PINPad появится текст сообщения, а функция будет ожидать нажатия пользователем кнопки подтверждения или отказа от операции на экране Рутокен PINPad.
Если пользователь подтверждает выполнение операции, то сообщение сначала хешируется внутри Рутокен PINPad, а затем подписывается. Функция C_Sign()
возвращает управление и 64-байтовый блок сформированной цифровой подписи .
Если пользователь отклоняет операцию подписи, функция C_Sign()
немедленно возвращает управление и код ошибки. Никаких вычислений хеша или цифровой подписи не производится.
Подпись на Рутокен PINPad отдельными механизмами хеширования и подписи
При использовании отдельных механизмов хеширования и подписи сначала в функцию C_Digest()
с механизмом хеширования (например, CKM_GOSTR3411
) передается текст в специальном формате для отображения его на экране Рутокен PINPad.
При вызове функция C_Digest()
вычисляет хеш и возвращает управление вместе с значением хеша. Исходное сообщение и значение хеша запоминаются внутри Рутокен PINPad.
Затем вызывается функция C_Sign()
с механизмом подписи (например, CKM_GOSTR3410
) и произвольным значением хеша. Рутокен PINPad подставляет сохраненное значение хеша вместо переданного функцией C_Sign()
значения и отображает на экране текст исходного сообщения. Функция C_Sign()
ожидает нажатия пользователем кнопки подтверждения или отказа от операции на экране Рутокен PINPad.
Если пользователь подтверждает выполнение операции, то сохраненное значение хеша в Рутокен PINPad подписывается, и функция C_Sign()
возвращает управление и 64-байтовый блок сформированной цифровой подписи.
Если пользователь отклоняет операцию подписи, функция C_Sign()
немедленно возвращает управление и код ошибки. Вычисления цифровой подписи не производится.
Пример подписи данных по алгоритму ГОСТ Р 34.10-2001
Code Block | ||||
---|---|---|---|---|
| ||||
/* Механизм подписи/проверки подписи по алгоритму ГОСТ Р 34.10-2001 */ CK_MECHANISM SigVerMech = {CKM_GOSTR3410, NULL_PTR, 0}; /* Набор параметров КриптоПро алгоритма ГОСТ Р 34.11-1994 */ CK_BYTE GOST3411params[] = { 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x1e, 0x01 }; /* Механизм подписи/проверки подписи по алгоритму ГОСТ Р 34.10-2001 с хешированием по алгоритму ГОСТ Р 34.11-94*/ CK_MECHANISM HashSigVerMech = {CKM_GOSTR3410_WITH_GOSTR3411, GOST3411params, sizeof(GOST3411params)}; CK_BYTE_PTR pbtSignature = NULL_PTR; // Указатель на буфер, содержащий подпись для исходных данных CK_ULONG ulSignatureSize = 0; // Размер буфера, содержащего подпись для исходных данных, в байтах while(TRUE) { ... /* Инициализировать операцию подписи данных CK_MECHANISM HashSigVerMech = {CKM_GOSTR3410_WITH_GOSTR3411, GOST3411params, sizeof(GOST3411params)}; CK_BYTE_PTR pbtSignature = NULL_PTR; // Указатель на буфер, содержащий подпись для исходных данных CK_ULONG ulSignatureSize = 0; // Размер буфера, содержащего подпись для исходных данных, в байтах while(TRUE) { ... /* Инициализировать операцию подписи данных */ printf("C_SignInit"); rv = pFunctionList->C_SignInit( hSession, // Хэндл сессии &SigVerMech, // Механизм подписи hPrivateKey ); // Хэндл закрытого ключа if (rv != CKR_OK) { printf(" -> Failed\n"); break; } printf(" -> OK\n"); /* Определить размер подписанных данных */ printf("C_Sign step 1"); rv = pFunctionList->C_Sign( hSession, // Хэндл сессии pbtHash, // Буфер с данными для подписи ulHashSize, // Длина подписываемых данных pbtSignature, // Буфер с подписанными данными &ulSignatureSize); // Длина подписанных данных if (rv != CKR_OK) { printf(" -> Failed\n"); break; } printf(" -> OK\n"); pbtSignature = (CK_BYTE*)malloc(ulSignatureSize); memset( pbtSignature, 0, ulSignatureSize * sizeof(CK_BYTE)); /* Подписать исходные данные */ printf("C_SignInitSign step 2"); rv = pFunctionList->C_SignInitSign( hSession, // Хэндл сессии pbHash, // Буфер с данными для подписи ulHashSize, &SigVerMech,// Длина подписываемых данных pbtSignature, // Буфер с Механизмподписанными подписиданными hPrivateKey &ulSignatureSize); // ХэндлДлина закрытогоподписанных ключаданных if (rv != CKR_OK) { printf(" -> Failed\n"); break; } printf(" -> OK\n"); /* ОпределитьРаспечатать размербуфер, подписанныхсодержащий данныхподпись */ printf("C_Sign step 1Signature buffer is: \n"); rv = pFunctionList->C_Sign( hSession, // Хэндл сессии pbtHash, // Буфер с данными для подписи ulHashSize, // Длина подписываемых данных pbtSignature, // Буфер с подписанными данными &ulSignatureSize); // Длина подписанных данных if (rv != CKR_OK) { printf(" -> Failed\n"); break; } printf(" -> OK\n"); pbtSignature = (CK_BYTE*)malloc(ulSignatureSize); memset( pbtSignature, 0, ulSignatureSize * sizeof(CK_BYTE)); /* Подписать исходные данные */ printf("C_Sign step 2"); rv = pFunctionList->C_Sign( hSession,for (i = 0; i < ulSignatureSize; i++) { printf("%02X ", pbtSignature[i]); if ((i + 1) % 8 == 0) printf("\n"); } |
Подпись данных в формате CMS (PKCS#7)
Для вычисления подписи в формате PKCS#7 существует функция C_EX_PKCS7Sign(),
в которую сразу передаются все необходимые для операции данные. Для такой подписи необходимо наличие сертификата, которым будут подписываться данные.
После окончания работы с функцией необходимо освободить буфер, содержащий подпись, вызвав функцию C_EX_FreeBuffer().
Code Block | ||||
---|---|---|---|---|
| ||||
CK_OBJECT_HANDLE hCert; // Хэндл сертификата ... /* Подпись данных */ printf("PKCS7 Sign"); rv = pFunctionListEx->C_EX_PKCS7Sign( hSession, // Хэндл сессии pbHash pbtData, // Буфер с данными для подписи ulHashSize arraysize(pbtData), // Размер данных для подписи hCert, // ДлинаХэндл подписываемых данныхсертификата &pbtSignature, // Буфер для сподписанных подписаннымиданных данными &ulSignatureSize);, // ДлинаРазмер подписанных данных if (rv != CKR_OK) { printf(" -> Failed\n"); break; } printf(" -> OK\n"); /* Распечатать буфер, содержащий подпись */ printf("Signature buffer is: \n"); for (i = 0; i < ulSignatureSize; i++) { printf("%02X ", pbtSignature[i]); if ((i + 1) % 8 == 0) printf("\n"); } |
Подпись данных в формате CMS (PKCS#7)
Для вычисления подписи в формате PKCS#7 существует функция C_EX_PKCS7Sign(),
в которую сразу передаются все необходимые для операции данные. Для такой подписи необходимо наличие сертификата, которым будут подписываться данные.
После окончания работы с функцией необходимо освободить буфер, содержащий подпись, вызвав функцию C_EX_FreeBuffer().
hPrvKey, // Хэндл закрытого ключа, соответствующего сертификату
NULL, // Указатель на массив сертификатов
0, // Размер массива
0); // Формат подписи: 0 - неотделяемая подпись (подпись вместе с исходными данными);
// PKCS7_DETACHED_SIGNATURE - отделяемая подпись (подпись без исходных данных)
if (rv != CKR_OK)
printf(" -> Failed\n");
else
printf(" -> OK\n");
...
/* Освобождение памяти*/
printf("C_EX_FreeBuffer");
rv = pFunctionListEx->C_EX_FreeBuffer(pbtSignature);
if (rv != CKR_OK)
printf(" -> Failed\n");
else
printf(" -> OK\n"); |
Проверка подписи
Для проверки подписи данных служат функции C_Verify
и Init()
C_Verify()
. Сначала операцию подписи нужно инициализировать через C_VerifyInit()
, передав в нее идентификатор сессии, механизма и открытого ключа. Затем можно проверить подпись функцией C_Verify()
.
При использовании совместных механизмов хеширования и подписи (например, CKM_GOSTR3410_WITH_GOSTR3411)
в C_Verify
передается исходный текст, при использовании отдельного механизма подписи (например, ()
CKM_GOSTR3410
) – предварительно прохешированные функцией C_Digest()
исходные данные.
Code Block | ||||
---|---|---|---|---|
| ||||
while(TRUE)
{
...
/* Инициализировать операцию проверки подписи */
printf(" C_VerifyInit");
rv = pFunctionList->C_VerifyInit(hSession, // Хэндл сессии | ||||
Code Block | ||||
| ||||
CK_OBJECT_HANDLE hCert; // Хэндл сертификата ... /* Подпись данных */ printf("PKCS7 Sign"); rv = pFunctionListEx->C_EX_PKCS7Sign( hSession, // Хэндл сессии pbtData, // Буфер с данными для подписи arraysize(pbtData), // Размер данных для подписи hCert, // Хэндл сертификата &pbtSignatureSigVerMech, // Буфер для подписанных данных Механизм подписи &ulSignatureSize, hPublicKey); // РазмерХэндл подписанныхоткрытого данных ключа hPrvKey, // Хэндл закрытого ключа, соответствующего сертификату NULL, // Указатель на массив сертификатов 0, // Размер массива if (rv != CKR_OK) { printf(" -> Failed\n"); break; } printf(" -> OK\n"); /* Проверить подпись для исходных данных */ printf(" C_Verify"); rv = pFunctionList->C_Verify(hSession, // Хэндл сессии 0); pbHash, // ФорматБуфер подписи:с 0исходным -сообщением неотделяемаяили подписьзначением (подпись вместе с исходными данными); его хеша ulHashSize, // Длина буфера pbtSignature, // PKCS7_DETACHED_SIGNATURE - отделяемая подпись (подпись без исходных данных) if (rv != CKR_OK) printf(" -> Failed\n"); else printf(" -> OK\n"); ... /* Освобождение памяти*/ printf("C_EX_FreeBuffer"); rv = pFunctionListEx->C_EX_FreeBuffer(pbtSignature); Буфер с подписью ulSignatureSize); // Длина подписи if (rv != CKR_OK) { printf(" -> Failed\n"); break; else } printf(" -> OK\n"); |
Проверка подписи
Для проверки подписи данных служат функции C_SignInit()
и C_Sign()
. Сначала операцию подписи нужно инициализировать через C_SignInit()
, передав в нее идентификатор сессии, механизма и закрытого ключа. Затем размер буфера подписанных данных можно определить, вызвав C_Sign()
, и подписать данные, вызвав C_Sign()
второй раз.
При использовании совместных алгоритмов хеширования и подписи (например, CKM_GOSTR3410_WITH_GOSTR3411)
в C_Sign()
передается открытый текст для подписи, при использовании только алгоритма подписи (например, CKM_GOSTR3410
) – уже прохешированные данные.
Code Block | ||||
---|---|---|---|---|
| ||||
|
;
break;
}
...
if (pbtSignature)
{
free(pbtSignature);
pbtSignature = NULL_PTR;
}
if (pbHash)
{
free(pbHash);
pbHash= NULL_PTR;
} |
Шифрование и расшифрование
...
CKM_GOST28147_ECB
для шифрования алгоритмом ГОСТ 28147-89 в режиме простой замены,CKM_GOST28147
для шифрования алгоритмом ГОСТ 28147-89 в режимах гаммирования и режиме гаммирования с обратной связью,CKM_RSA_PKCS
для шифрования алгоритмом RSA.
Режим гаммирования
Режим гаммирования с обратной связью
Работа с токеном
Форматирование
Смена пин-кода
Работа с сертификатами
Создание подписанного запроса на сертификат в формате PKCS#10
Получение информации о сертификате
...