25.02.2003 16:03:44Использование CAPICOM 2.0 Ответов: 6
Vladimir
Всем доброго времени суток.
Не первый раз работаю с CAPICOM и вот недавно столкнулся с одной проблемой. При использованиие определенных параметров при дешифровании возникает ошибка: ASN1 unexpected end of data, код: -2146881278.
Ошибка возникает не стабильно. Приложение проводит шифование/дешифрование файла и ошибка возникает при работе с некоторыми файлами, но не со всеми. Изменение параметров алгоритма и длины ключа на появление ошибки не влияет. Для уменьшения размера зашифрованного файла используется encoding type = CAPICOM_ENCODE_BINARY, только тогда может возникать ошибка, если же использовать CAPICOM_ENCODE_BASE64, то ошибка не возникает. Может быть какая-то ошибка в CAPICOM?
 
Ответы:
28.02.2003 14:30:37Василий
Не могли бы Вы уточнить,
1) всегда ли используется блочное шифрование при возникновении ошибки и 2) нет ли связи между фактом появления ошибки и кратностью длины файла размеру блока?
28.02.2003 14:58:50Vladimir
Спасибо, что откликнулись!
Хочу сразу сказать, что мои познания в криптографии практически никакие. Использую уже готорые средства на прикладном уровне.
Поэтому по первому пункту к сожелению ничего сказать не могу, т. к. про блочное шифрование только и слышал, что оно есть. По второму - я менял размерность файла, но зависимость появления ошибки к сожелению не нашел. Ниже я привел простой пример, при котором выскакивает ошибка.

Dim envData As New CAPICOM.EnvelopedData()
envData.Algorithm.Name = 0
envData.Algorithm.KeyLength = 0
envData.Recipients.Add(cert) ’ в cert уже определен сертификат
buffer = New String("a", 1024) ’ Просто 1024 символов "a"
envData.Content = buffer
envString = envData.Encrypt(CAPICOM.CAPICOM_ENCODING_TYPE.CAPICOM_ENCODE_BINARY)

потом раскодируем...

envData = New CAPICOM.EnvelopedData()
envData.Decrypt(envString)

Этот блок в try catch и выдает exception :(

при этом, если использовать encoding с параметром CAPICOM.CAPICOM_ENCODING_TYPE.CAPICOM_ENCODE_BASE64, то раскодирование пройдет успешно.
До этого я эксперементировал в файлами, но сейчас пока все выбросил и эксперементирую только со строкой. Если будет, что-то интересное, то обязательно сообщу.

P.S. Я много рыл в интеренете, пытаясь найти почему так происходит. Нашел практически такой же вопрос на MS сайте человека из России и ему ответили только из вашей компании :), но к сожелению только шуткой, советовали поискать.
Мне очень важно понять - ошибка ли это в моих действиях или все-таки проблема с CAPICOM.
P.P.S. Сейчас я использую библиотеку в VB.NET, до этого проводил эксперименты под броузером и в Lotus Notes, но там у меня такой задачи по binary кодированию небыло.
Да еще, CAPICOM версия 2.0.0.1
28.02.2003 16:05:17Vladimir
Небольшое дополнение.
При изменении кода алгоритма - декриптование в некоторых случаях прошло.
При 0 (RC2) - не прошло.
При 1 (RC4) - прошло.
При 2 (DES) - не прошло.
При 3 (3DES) - прошло.
При 4 (AES) - сообщение, что такой тип вообще неизвестен, хотя в CAPICOM константах он есть. Пока не знаю что это значит.
28.02.2003 17:08:54Алексей
Сразу скажу, что не силен в .NET.
Но скорее всего, ошибка возникает из-за преобразования типов (переменная envString).
Сталкивался с примерно такой проблемой в VB 6.0.
После того как на Encrypt подавал не переменную типа String, а массив байтов
(aVar() as Byte), проблема была ликвидирована. CAPICOM показывает в intellisense, что эти параметры должны быть типа String - попробуйте проигнорировать это - подайте массив байтов. На Decrypt - тоже присваиваем возвращаемое значение переменной типа массива байтов. Не знаю как поведет себя при этом VB.NET, но VB 6 - показал себя молодцом.

При работе с файлами - чтение осуществлялось также в массив байтов, запись результата - тоже из переменной типа массива байтов.

Private Function prvReadBinFile(InFile As String) As Byte()
Dim fn As Integer
Dim Txt() As Byte
fn = FreeFile
Open InFile For Binary Access Read As #fn
lSrcLen = LOF(fn)
ReDim Txt(lSrcLen - 1)
Get #fn, , Txt
Close #fn
prvReadBinFile = Txt
End Function

Private Function prvWriteBinFile(fname, bArr() As Byte) As Boolean
Dim fn As Integer
fn = FreeFile
Open fname For Binary Access Write As #fn
Put #fn, , bArr
Close #fn
End Function

Процедура шифрования:

Dim Envmessage As New CAPICOM.EnvelopedData

Envmessage.Content = prvReadBinFile(InFile)
Envmessage.Recipients.Add oCert
prvWriteBinFile OutFile, Envmessage.Encrypt(CAPICOM_ENCODE_BINARY)
Set Envmessage = Nothing
28.02.2003 17:14:21Алексей
Забыл.
Процедура расшифрования - аналогично

Dim Envmessage As New EnvelopedData
Envmessage.Decrypt prvReadBinFile(InFile)
prvWriteBinFile OutFile, Envmessage.Content
Set Envmessage = Nothing
28.02.2003 18:20:11Vladimir
Все спасибо!
К сожелению в .NET не все так просто с преобразованиями строк и байт. Т. е. преобразовать можно, но "все по честному" ;).
Я немного продвинулся в решении. Как уже писал, с RC2 и DES - проблемы, но думаю причину еще можно попробывать поискать. Остановился пока на RC4, пока вроде все кодировал-раскодировал было нормально. Как я говорил из меня тот еще "криптолог", в глубины не лезу. С RC4 врозникли проблемы при большом объеме данных, вроде как после 64Kb. Но вроде как можно сделать следующее:
- использовать алгоритм RC4;
- кодирование провести как Base64;
- над полученной строкой провести decoding классом CAPICOM.Utilites функцией Base64Decode.
Полученную строку сохраняем как массив байт. В итоге закодированный файл будет больше исходного на пару сотен байт, а не почти в три раза больше. Если больше никаких гадостей не вылезет, то для меня это в принципе какое-никакое решение.
P.S. Но все-таки все равно интересно почему в CAPICOM кодирование-раскодирование странно работает?