C_DecryptInit
¶Примечание
Функции C_Decrypt()
, C_DecryptUpdate()
и C_DecryptFinal()
не возвращают предусмотренного
стандартом PKCS #11 кода ошибки CKR_ENCRYPTED_DATA_INVALID
(недопустимые зашифрованные данные).
C_DecryptInit
(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey)¶Параметры: |
|
---|
Инициализирует и задает параметры для операции расшифрования. Поддерживается как аппаратное, так и программное расшифрование.
Особенности апплетов:
Криптотокен 2 ЭП
Аппаратное шифрование
Для аппаратного шифрования используется виртуальный секретный ключ.
Данный ключ должен быть предварительно импортирован с помощью функции C_UnwrapKey()
или
сгенерирован и экспортирован с помощью функции C_WrapKey()
.
При использовании виртуального секретного ключа функция инициализирует операцию зашифрования по ГОСТ 28147–89 с параметрами id-tc26-gost-28147-param-Z.
CKA_KT2_KEY_ACTIVE
принимает значение CK_TRUE
, ключ готов к криптографическому преобразованию.CKA_KT2_KEY_ACTIVE
принимает значение CK_FALSE
.Программное шифрование
Программное шифрование применяется стандартным способом.
Для программного шифрования доступен атрибут CKA_KT2_KEY_MESHING
.
Если атрибут имеет значение CK_TRUE
, применяется алгоритм усложнения ключей для ГОСТ 28147–89 RFC 4357 п.2.3.2.
Поддерживаются следующие механизмы:
CKM_GOST28147_ECB
(0x00001221
) – механизм для симметричного шифра в режиме ECB по стандарту ГОСТ 28147–89.CKM_GOST28147
(0x00001222
) – механизм для симметричного шифра в режиме CFB по стандарту ГОСТ 28147–89.CKM_GOST28147_ECB
(0x00001221
) – механизм для симметричного шифра в режиме ECB по стандарту ГОСТ 28147–89.CKM_GOST28147
(0x00001222
) – механизм для симметричного шифра в режиме CFB по стандарту ГОСТ 28147–89.CKM_RSA_PKCS
(0x00000001
) – механизм для асимметричного шифра RSA. Также используется для ЭП.CKM_RSA_PKCS_OAEP
(0x00000009
) – механизм для асимметричного шифра RSA с использованием OAEP.CKM_DES3_ECB
(0x00000132
) – механизм для симметричного шифра triple-DES в режиме ECB.CKM_DES3_CBC
(0x00000133
) – механизм для симметричного шифра triple-DES в режиме CBC.CKM_AES_ECB
(0x00001081
) – механизм для симметричного шифра AES в режиме ECB.CKM_AES_CBC
(0x00001082
) – механизм для симметричного шифра AES в режиме CBC.Запускается в режимах
См.также
Результат: |
Совет Полный список ошибок см. в приложении. |
---|
C_Decrypt
¶C_Decrypt
(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedData, CK_ULONG_PTR pulEncryptedDataLen, CK_BYTE_PTR pData, CK_ULONG ulDataLen, )¶Параметры: |
|
---|
Осуществляет единоразовое расшифрование (по ГОСТ 28147-89), т.е расшифровывает только один блок данных.
Предупреждение
При шифровании с использованием механизма CKM_GOST28147_ECB
длина данных должна быть кратной 8 байт.
Запускается в режимах
См.также
Результат: |
Совет Полный список ошибок см. в приложении. |
---|
C_DecryptUpdate
¶C_DecryptUpdate
(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, CK_ULONG_PTR pulEncryptedPartLen)¶Параметры: |
|
---|
Продолжает составную операцию расшифрования – расшифровывает очередной блок данных.
Предупреждение
При шифровании с использованием механизма CKM_GOST28147_ECB
длина данных должна быть кратной 8 байт.
Запускается в режимах
См.также
Результат: |
Совет Полный список ошибок см. в приложении. |
---|
C_DecryptFinal
¶C_DecryptFinal
(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pLastEncryptedPart, CK_ULONG_PTR pulLastEncryptedPartLen)¶Параметры: |
|
---|
Завершает составную операцию расшифрования.
Запускается в режимах
См.также
Результат: |
Совет Полный список ошибок см. в приложении. |
---|
Для обеспечения успешного расшифрования данных, необходимо, чтобы функции в алгоритме были использованы в одной из следующих последовательностей:
Для единоразовой операции расшифрования | Для составной операции расшифрования |
---|---|
|
Пример реализации зашифрования на языке C:
// сеанс PKCS#11
CK_SESSION_HANDLE pkcs11SessionHandle;
// механизм расшифрования ГОСТ 28147-89
CK_MECHANISM pkcs11DecMechanism;
// дескриптор сессионного ключа PKCS#11
CK_OBJECT_HANDLE pkcs11SessionKeyHandle;
// текст, зашифрованный PKCS#11
CK_BYTE pkcs11EncText[8];
// длина текста, зашифрованного PKCS#11
CK_ULONG pkcs11EncTextLength = sizeof(pkcs11EncText);
// открытый текст
CK_BYTE plainText[8];
// длина открытого текста
CK_ULONG plainTextLength = sizeof(plainText);
// инициализационный вектор для шифрования
CK_BYTE encIV[8];
// длина открытого текста
CK_ULONG encIVLength = sizeof(encIV);
// устанавливаем механизм шифрования по ГОСТ 28147-89
pkcs11DecMechanism.mechanism = CKM_GOST28147;
pkcs11DecMechanism.pParameter = encIV;
pkcs11DecMechanism.ulParameterLen = encIVLength;
// инициализируем операцию расшифрования
rv = C_DecryptInit(pkcs11SessionHandle, &pkcs11DecMechanism, pkcs11SessionKeyHandle);
if(rv != CKR_OK)
{
PrintError("C_DecryptInit", rv);
return;
}
// расшифровываем зашифрованный текст
rv = C_Decrypt(pkcs11SessionHandle, pkcs11EncText, pkcs11EncTextLength, plainText, &plainTextLength);
if(rv != CKR_OK)
{
PrintError("C_Decrypt", rv);
return;
}
Пример аппаратного расшифрования с использованием виртуального секретного ключа на языке C++:
CK_BBOOL bTrue = CK_TRUE;
CK_BBOOL bFalse = CK_FALSE;
// зашифрованные данные
CK_BYTE encrypted[] = { ... };
// размер зашифрованных данных
CK_ULONG nEncrypted = 8;
// буфер расшифрованных данных
CK_BYTE decrypted[8] = { 0x00 };
// размер буфера расшифрованных данных
CK_ULONG nDecrypted = 8;
// получение дескриптора сессии (см. C_OpenSession)
CK_SESSION_HANDLE hSession = ... ;
// получение закрытого ключа Отправителя
CK_OBJECT_HANDLE hSenderPrivateKey = ... ;
// получение открытого ключа Получателя
CK_OBJECT_HANDLE hReceiverPublicKey = ... ;
/*
В данном примере для генерации ключевых пар использовались следующие параметры:
1. Механизм генерации ключей:
CK_MECHANISM ckKeyGenMach = { CKM_GOSTR3410_256_KEY_PAIR_GEN, NULL_PTR, 0 };
2. Шаблон закрытого ключа:
CK_ATTRIBUTE privateKeyAttributes[] =
{
{ CKA_TOKEN, &bTrue, sizeof(bTrue) },
{ CKA_PRIVATE, &bTrue, sizeof(bTrue) },
{ CKA_WRAP, &bTrue, sizeof(bTrue) },
{ CKA_UNWRAP, &bTrue, sizeof(bTrue) },
};
3. Шаблон открытого ключа:
CK_ATTRIBUTE publicKeyAttributes[] =
{
{ CKA_TOKEN, &bTrue, sizeof(bTrue) },
{ CKA_PRIVATE, &bFalse, sizeof(bFalse) },
{ CKA_GOSTR3410_PARAMS, id_GostR3410_2001_CryptoPro_XchA_ParamSet, sizeof(id_GostR3410_2001_CryptoPro_XchA_ParamSet) },
{ CKA_GOSTR3411_PARAMS, id_tc26_gost3411_12_256, sizeof(id_tc26_gost3411_12_256) },
{ CKA_WRAP, &bTrue, sizeof(bTrue) },
{ CKA_UNWRAP, &bTrue, sizeof(bTrue) },
};
*/
CK_OBJECT_CLASS ckaClass = CKO_SECRET_KEY;
CK_BYTE ckaId[] = "VSKO_ID"; // "VSKO_ID"
// атрибуты поиска виртуального ключа
CK_ATTRIBUTE searchAtt[] = {
{CKA_CLASS, &ckaClass, sizeof(ckaClass)},
{CKA_ID, ckaId, sizeof(ckaId) - 1}
};
CK_OBJECT_HANDLE hVirtualSecretKey = CK_INVALID_HANDLE; // дескриптор виртуального секретного ключа
CK_ULONG ulObjectsCount = 5;
// поиск виртуального ключа
C_FindObjectsInit(hSession, searchAtt, 2);
C_FindObjects(hSession, &hVirtualSecretKey, 1, &ulObjectsCount);
C_FindObjectsFinal(hSession);
// параметры экспорта ключа
CK_GOSTR3410_KEY_WRAP_PARAMS wrapParams;
memset(&wrapParams, 0, sizeof(wrapParams));
wrapParams.hKey = hSenderPrivateKey;
CK_MECHANISM ckWrapMechanism;
ckWrapMechanism.mechanism = CKM_GOSTR3410_KEY_WRAP;
ckWrapMechanism.pParameter = &wrapParams;
ckWrapMechanism.ulParameterLen = sizeof(wrapParams);
// получаем требуемый размер для экспортного представления
CK_ULONG wrappedKeySize = 0;
C_WrapKey(hSession, &ckWrapMechanism, hReceiverPublicKey, hVirtualSecretKey, NULL, &wrappedKeySize);
// генерируем и экспортируем ключ hVirtualSecretKey
std::vector<CK_BYTE> wrappedKey(wrappedKeySize);
C_WrapKey(hSession, &ckWrapMechanism, hReceiverPublicKey, hVirtualSecretKey, &wrappedKey[0], &wrappedKeySize);
CK_BYTE plain[] = "12345678";
CK_BYTE encrypted[8] = {0x00};
CK_ULONG nEncrypted = 8;
CK_MECHANISM ckEncryptMech = { CKM_GOST28147 };
C_EncryptInit(hSession, &ckEncryptMech, hVirtualSecretKey);
C_Encrypt(hSession, &plain[0], 8, &encrypted[0], &nEncrypted);
// шаблон секретного ключа
CK_OBJECT_CLASS objectClass = CKO_SECRET_KEY;
CK_KEY_TYPE keyType = CKK_GOST28147;
CK_ATTRIBUTE secretKeyTemplate[] =
{
{CKA_GOST28147_PARAMS, STR_CRYPTO_PRO_GOST28147_Z, STR_CRYPTO_PRO_GOST28147_Z_SIZE},
{CKA_TOKEN, &s_TrueValue, sizeof(s_TrueValue)},
{CKA_PRIVATE, &s_TrueValue, sizeof(s_TrueValue)},
{CKA_CLASS, &objectClass, sizeof(objectClass)},
{CKA_KEY_TYPE, &keyType, sizeof(keyType)},
{CKA_DECRYPT, &s_TrueValue, sizeof(s_TrueValue)}
};
CK_OBJECT_HANDLE hCEK = CK_INVALID_HANDLE;
// импорт ключа в память изделия
wrapParams.hKey = hSenderPublicKey;
C_UnwrapKey(hSession, &ckWrapMechanism, hReceiverPrivateKey, &wrappedKey[0], wrappedKeySize, secretKeyTemplate, 6, &hCEK);
CK_BYTE decrypted[8] = { 0x00 };
CK_ULONG nDecrypted = 8;
CK_MECHANISM ckDecryptMech = { CKM_GOST28147 };
C_DecryptInit(hSession, &ckDecryptMech, hCEK);
C_Decrypt(hSession, &encrypted[0], 8, &decrypted[0], &nDecrypted);