Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > C/C++: Системное программирование и WinAPI > Crypto api RC2 |
Автор: frying 2.5.2012, 20:13 | ||
Доброго времени суток! Проблема такая: почему-то зашифрованные данные ничем не отличаются от исходных. В чём ошибка не понятно.
Проверялось на Visual C++. |
Автор: feodorv 2.5.2012, 22:36 |
А это что такое: Почему strlen? Как это вообще могло работать??? |
Автор: GremlinProg 3.5.2012, 06:27 |
в принципе, могло бы: а вот здесь, думаю есть ошибка: CryptEncrypt возвращает чсисло зашифрованных байт в count3, так что если там 0, вполне возможно, что данные на выходе остались неизменными, наверное, что-то не так с логикой: флаги, порядок вызовов API и т.п. |
Автор: frying 3.5.2012, 06:39 | ||
Попробовал сделать так:
На экране всё время выводится 8. Насчёт флагов - ведь там сейчас всего один действующий flag, который показывает последний блок из файла или нет будет передан. |
Автор: GremlinProg 3.5.2012, 06:53 |
флаг тут может быть только 0 либо CRYPT_OAEP, ничего другого быть не должно, а последний параметр должен принимать размер буфера buf3 в байтах, ни где не вижу, чтобы он был распределен на 40 байт, чтобы определить необходимый размер буфера, который требуется выделить для CryptEncrypt, необходимо вызвать его с pbData=NULL, тогда размер буфера будет возвращен в параметре pdwDataLen документация: http://msdn.microsoft.com/en-us/library/windows/desktop/aa379924(v=vs.85).aspx |
Автор: frying 4.5.2012, 07:01 | ||
GremlinProg, флаг нужен, в спецификации он называется Final. Пробую получить размер буфера:
Но pdwDataLen всегда 0. Почему? |
Автор: GremlinProg 4.5.2012, 07:12 |
извиняюсь ![]() |
Автор: feodorv 4.5.2012, 09:59 | ||||
А чем оно инициализируется?
Скорее всего, там 0, что в купе с true даёт 0 в pdwDataLen... Добавлено через 3 минуты и 47 секунд
Кстати, переменную лучше назвать как dwDataLen, так как p... намекает на указатель ![]() |
Автор: frying 4.5.2012, 15:53 | ||
feodorv спасибо за совет, но я думал, что если dwDataLen будет всё равно инициализироваться в функции, зачем задавать начальное значение. Сейчас, если инициализирую нулём, то функция с флагом final = true даёт значение 8, если же final = false, то значение 0. Посмотрите, пожалуйста, переделанный код
Несколько блоков отрабатывают нормально, потом выбрасывается 234 ошибка cryptencrypt. Скажите в чём ошибка. |
Автор: feodorv 4.5.2012, 16:51 | ||
Нет, нет. Если в CryptEncrypt dwBufLen означает доступный размер буфера, то dwDataLen - число байт в буфере, которые нужно закриптовать. Дело в том, что для потоковых алгоритмов шифрование идёт байт в байт (хотя и в этом случае в конце в хвост зашифрованным данным могут быть записаны дополнительные байты), для блоковых (а CALG_RC2 - это блоковый алгоритм) шифрование осуществляется блоками бит (в Вашем случае - по 64 бита), поэтому если на входе будет, скажем, 2 байта, то на выходе уже 8! Соответственно, в этом случае до вызова CryptEncrypt устанавливаем dwDataLen в 2, а после вызова получаем значение 8. То есть dwDataLen - это аргумент функции, который как передаёт значение в функцию при её вызове, так и получает возвращаемое значение из функции. Поэтому dwDataLen нужно (правильно!) инициализировать до вызова CryptEncrypt Код посмотрю, но попозже... Кстати, CryptAcquireContext в начале программы Вы делаете, а CryptReleaseContext в конце - нет. |
Автор: feodorv 4.5.2012, 18:14 | ||||||||
Основное, что я вижу не так, это одновременное шифрование-дешифрование. Это очень плохо. Во-первых, в общем случае, состояние ключа может зависеть от шифруемых данных, и если мы сначала зашифруем buf1, а потом buf2, то результат может отличаться от того, который получен, если сначала зашифровать buf2, а потом buf1. То же с одновременным шифрованием-дешифрованием: состояние ключа в случае
может отличаться от того, который получим при
В результате мы не сможем правильно дешифровать данные. У Вас всё ещё хуже: Вы два раза подряд запрашиваете функции шифрования с finish, равной TRUE. При первом TRUE ключ уже невозвратимо искажается:
При втором TRUE ключ переиницилизирован, и CryptDecrypt дешифрует неизвестно что... То есть: надо сначала (непрерывно) всё закриптовать (до финального TRUE) и уже потом всё разкриптовать (то же до финального TRUE). Добавлено @ 18:28 Кстати:
|
Автор: feodorv 4.5.2012, 19:43 | ||
Есть небольшая тонкость: при финализировании данных, выровненных по границе блока, CryptEncrypt в конец буфера добавляет дополнительный блок в 8 байт. То есть буфер требуется большей длины (на те самые 8 байт). То есть:
Но вообще, логику программы стоит переделать... |
Автор: frying 9.5.2012, 13:48 | ||
feodorv, большое спасибо за развёрнутый ответ. Сделал сейчас по-другому: просто весь текст передаю одним блоком и шифрую. Основная моя ошибка была в том, что
Т.е. для шифрованного теста буфер должен изначально подходить. |