Page tree

Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Открытие и закрытие сессии

// Про колбэк

Code Block
languagecpp
titleМониторинг событий в слотах
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
languagecpp
titleФормат данных Рутокен PINPad
<!PINPADFILE RU> 	// обязательный признак строки, которая будет распознаваться Rutoken PINPad
<!>some text 		// текст, нераспознаваемый Rutoken PINPad
<N>some text 		// наименование поля
<V>some text 		// значение поля

Пример отформатированных данных для Рутокен PINPad

Code Block
languagecpp
titleПлатежное поручение в текстовом виде
ФИО: Петров Петр Петрович Москва, Пионерская ул, д. 3, кв. 72
Перевод со счета : 42301810001000075212
Сумма : 150000
Валюта : RUR
Наименование получателя : Иванова Елена Ивановна
Номер счета получателя : 40817810338295201618
БИК банка получателя : 044525225
Наименование банка получателя : ОАО 'СБЕРБАНК РОССИИ' Г. МОСКВА
Номер счета банка получателя : 30101810400000000225
Назначение платежа : перевод личных средств
Code Block
languagecpp
titleПлатежное поручение в распознаваемом Рутокен PINPad виде
<!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
languagecpp
titleПлатежное поручение в распознаваемом Рутокен PINPad виде (ANSI-строка)
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
languagecpp
titleПлатежное поручение в виде двоичной строки
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
languagecpp
titleПлатежное поручение в текстовом виде
ФИО: Петров Петр Петрович Москва, Пионерская ул, д. 3, кв. 72
Перевод со счета : 42301810001000075212
Сумма : 150000
Валюта : RUR
Наименование получателя : Иванова Елена Ивановна
Номер счета получателя : 40817810338295201618
БИК банка получателя : 044525225
Наименование банка получателя : ОАО 'СБЕРБАНК РОССИИ' Г. МОСКВА
Номер счета банка получателя : 30101810400000000225
Назначение платежа : перевод личных средств
Code Block
languagecpp
titleПлатежное поручение в распознаваемом Рутокен PINPad виде
<!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
languagecpp
titleПлатежное поручение в распознаваемом Рутокен PINPad виде (ANSI-строка)
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
languagecpp
titleПлатежное поручение в виде двоичной строки
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
languagecpp
titleПодпись данных по алгоритму ГОСТ Р 34.10-2001
/* Механизм подписи/проверки подписи по алгоритму ГОСТ Р 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
languagecpp
titleПодпись данных в формате CMS (PKCS#7)
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_VerifyInit() и C_Verify(). Сначала операцию подписи нужно инициализировать через C_VerifyInit(), передав в нее идентификатор сессии, механизма и открытого ключа. Затем можно проверить подпись функцией C_Verify().

При использовании совместных механизмов хеширования и подписи (например, CKM_GOSTR3410_WITH_GOSTR3411) в  C_Verify() передается исходный текст, при использовании отдельного механизма подписи (например, CKM_GOSTR3410) – предварительно прохешированные функцией C_Digest() исходные данные.

Code Block
languagecpp
titleПроверка подписи по алгоритму ГОСТ Р 34.10-2001
while(TRUE)
{
	...
	/* Инициализировать операцию проверки подписи */
	printf(" C_VerifyInit");
	rv = pFunctionList->C_VerifyInit(hSession,    	// Хэндл сессии
Code Block
languagecpp
titleПодпись данных в формате CMS (PKCS#7)
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
languagecpp
titleПроверка подписи по алгоритму ГОСТ Р 34.10-2001
 
;
	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

Получение информации о сертификате

...