Как правильно C_Decrypt в pkcs # 11? - PullRequest
2 голосов
/ 29 июня 2019

Я использую C_Decrypt с механизмом CKM_AES_CBC_PAD.Я знаю, что мой зашифрованный текст длиной 272 байта должен фактически расшифровываться до 256 байтов, что означает, что был добавлен полный блок заполнения.

Я знаю, что согласно стандарту при вызове C_Decrypt с выходным буфером NULL функция может вернуть выходную длину, которая несколько больше, чем фактическая требуемая длина, в частности, когда используется заполнение, это понятно, так как функция не может знать, сколько байтов заполнения находится в последнем блоке безвыполнение фактического дешифрования.

Таким образом, вопрос заключается в том, имеет ли смысл, если я знаю, что я должен получить ровно 256 байт обратно, как в сценарии, который я объяснил выше, то, что я все еще получаю CKR_BUFFER_TOO_SMALL ошибка в результате, несмотря на пропуск 256-байтового буфера?(Чтобы было понятно: я указываю, что это длина выходного буфера в соответствующем параметре длины выходного буфера, см. Параметры C_Decrypt , чтобы понять, что я имею в виду)

IЯ сталкиваюсь с таким поведением с устройством Safenet Luna и не уверен, что с ним делать.Это ошибка моего кода в том, что он сначала не запросил длину, передав NULL в выходной буфер, или это ошибка на стороне библиотеки HSM / PKCS11?

Еще одна вещь, которую я, возможно, должен упомянуть, это то, что когда япредоставить 272 (256 + 16) байтов выходного буфера, вызов успешен, и я замечаю, что я получаю обратно свой ожидаемый открытый текст , но также и блок заполнения , что означает 16 последних байтов со значением 0x10.Однако длина вывода корректно обновляется до 256, , а не 272 - это также доказывает, что я не использую CKM_AES_CBC вместо CKM_AES_CBC_PAD случайно, что я тоже подозревал на мгновение:)

1 Ответ

1 голос
/ 10 июля 2019

Я использовал CKM.AES_CBC_PAD механизм заполнения с C_Decrypt в прошлом.Вам нужно сделать 2 вызова на C_Decrypt (1-й ==> Чтобы получить размер обычного текста, 2-й ==> Фактическая расшифровка) .см. документацию здесь , в которой говорится об определении длины буфера, необходимого для хранения простого текста.

Ниже приведен пошаговый код, демонстрирующий поведение дешифрования:

//Defining the decryption mechanism
CK_MECHANISM mechanism = new CK_MECHANISM(CKM.AES_CBC_PAD);

//Initialize to zero -> variable to hold size of plain text
LongRef lRefDec = new LongRef();

// Get ready to decrypt 
CryptokiEx.C_DecryptInit(session_1, mechanism, key_handleId_in_hsm);

// Get the size of the plain text -> 1st call to decrypt
CryptokiEx.C_Decrypt(session_1, your_cipher, your_cipher.length, null, lRefDec);

// Allocate space to the buffer to store plain text.  
byte[] clearText = new byte[(int)lRefDec.value];

// Actual decryption -> 2nd call to decrypt
CryptokiEx.C_Decrypt(session_1, eFileCipher, eFileCipher.length, eFileInClear,lRefDec);

Иногда дешифрование завершается ошибкой, поскольку ваши входные данные шифрования вводят в заблуждение (однако шифрование успешно, но соответствуетрасшифровка не удастся) алгоритм дешифрования.Поэтому важно не отправлять необработанные байты непосредственно в алгоритм шифрования;скорее кодирование входных данных с помощью схемы UTF-8/16 сохраняет данные от неправильного понимания как байты управления сетью.

...