| ||||
| ||||
// Есть два контейнера с уже созданными ключевыми парами AT_KEYEXCHANGE // Обмениваются сессионным // Первый создав и экспортировав сес. и пуб.ключ шифрует файл // Второй востановив сес.ключ его дешифрует // *********************** Проблема!!!!!!!!!!! ************************* // Хоть все отрабатывает "на ура" первые 8 байт расшифрованного битые // Есть не сохранять KP_IV в первом конт. и не передавать во второй // Если передавать, то все хорошо // Но тогда нарушается логика, или я что-то не уловил. // 1. Клиенты должны обменяться публичными ключами. // 2. Обменяться сессионным, шифруя его открытыми ключами друг - друга // 3. Обменяться шифрованными данными // // Где обмен KP_IV в этой схеме ??? // Далее код на дельфе (правда я его завернул в классы) // Открываю первый контейнер ’aaaa’ вашим провайдером Container1 := GNICrypto.AddProvider( GNIPS_GOST_2001 ); Result := Container1.Connect( ’aaaa’ ); if ( Result ) then begin // Открываю второй контейнер ’bbbb’ вашим провайдером Container2 := GNICrypto.AddProvider( GNIPS_GOST_2001 ); Result := Container2.Connect( ’bbbb’ ); end; if ( Result ) then begin // Из второго извлекаю уже существующий ключик AT_KEYEXCHANGE Key22 := Container2.Keys.Add; Result := Key22.Open( GNIKS_KEYEXCHANGE ); end; if ( Result ) then begin // И экспортирую его в PUBLICKEYBLOB pMemOpenKey.Clear; Result := Key22.Export( pMemOpenKey, GNIKB_PUBLIC ); end; if ( Result ) then begin // Теперь из первого извлекаю уже существующий AT_KEYEXCHANGE Key12 := Container1.Keys.Add; Result := Key12.Open( GNIKS_KEYEXCHANGE ); end; if ( Result ) then begin // Теперь на основании экспортированного публичного ключа второго контейнера // и публичного ключа из первого строю... эээээ... не знаю как это назавается // но он дает возможность нормально экспортировать и импортировать сессионный ключ Key13 := Container1.Keys.Add; pMemOpenKey.Seek( 0, soFromBeginning ); Result := Key13.Import( pMemOpenKey, Key12 ); pMemOpenKey.Clear; end; if ( Result ) then begin // Экспортирую публичный ключ из первого в PUBLICKEYBLOB pMemOpenKey.Clear; Result := Key12.Export( pMemOpenKey, GNIKB_PUBLIC ); end; if ( Result ) then begin // На первом создаю сессионный ключик с возможностью экспортирования Key11 := Container1.Keys.Add; Result := Key11.Add( GNIKS_G28147, [ GNIKFT_EXPORTABLE ] ); end; if ( Result ) then begin // На основании того ключа слияния двух публичных экспортирую сессионный из первого pMemSesKey.Clear; Result := Key11.Export( pMemSesKey, GNIKB_SIMPLE, Key13 ); end; if ( Result ) then begin // Теперь сливаю публичные ключи обоих контейнеров и во втором Key23 := Container2.Keys.Add; pMemOpenKey.Seek( 0, soFromBeginning ); Result := Key23.Import( pMemOpenKey, Key22 ); pMemOpenKey.Clear; end; if ( Result ) then begin // Импортирую сессионный ключ во второй используя слитый ключ Key21 := Container2.Keys.Add; pMemSesKey.Seek( 0, soFromBeginning ); Result := Key21.Import( pMemSesKey, Key23 ); pMemSesKey.Clear; end; //if ( Result ) then // Result := Key11.GetParameter( KP_IV, @Data1, @Data2, 0); if ( Result ) then // Шифрую begin AInStream := TFileStream.Create( GetCurrentDir + ’\help’, fmOpenRead ); AOutStream := TFileStream.Create( GetCurrentDir + ’\help_enc’, fmCreate ); Result := GNICrypto.Encrypt( AInStream, AOutStream, Key11 ); FreeAndNil( AOutStream ); FreeAndNil( AInStream ); end; //if ( Result ) then // Result := Key21.SetParameter( KP_IV, @Data1, 0); if ( Result ) then // Расшифровываю begin AInStream := TFileStream.Create( GetCurrentDir + ’\help_enc’, fmOpenRead ); AOutStream := TFileStream.Create( GetCurrentDir + ’\help_dec’, fmCreate ); if ( Result ) then Result := GNICrypto.Decrypt( AInStream, AOutStream, Key21 ); FreeAndNil( AOutStream ); FreeAndNil( AInStream ); end; | ||||
Ответы: | ||||
| ||||
Инитвектор задаётся случайным образом при создании ключа и меняется случайным образом при каждой операции шифрования. Соответственно, два варианта: 1) как на стороне отправителя, так и на стороне получателя задавать некоторое [заранее оговоренное или постоянное] значение IV до использования ключа. 2) снимать значение IV перед шифрованием, записывать его и передавать получателю, где устанавливать его до расшифрования. Высокоуровневые функции работы с сообщениями используют второй вариант (значение IV передаётся как одно из полей используемых структур данных) | ||||
| ||||
Спасибо. О том, что KP_IV можно задавать самому я из документации не уловил. Тогда пойду разбараться с сертификатами %) спасибо еще раз | ||||