11.04.2005 14:21:05Вопрос по KP_IV, 8 первым байтам, шифрации/дешифрации и о том, что именно необходимо передавать между двумя клиентами Ответов: 2
Альт
// Есть два контейнера с уже созданными ключевыми парами 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;
 
Ответы:
11.04.2005 14:37:58Василий
Инитвектор задаётся случайным образом при создании ключа и меняется случайным образом при каждой операции шифрования.
Соответственно, два варианта:
1) как на стороне отправителя, так и на стороне получателя задавать некоторое [заранее оговоренное или постоянное] значение IV до использования ключа.
2) снимать значение IV перед шифрованием, записывать его и передавать получателю, где устанавливать его до расшифрования.

Высокоуровневые функции работы с сообщениями используют второй вариант (значение IV передаётся как одно из полей используемых структур данных)
11.04.2005 17:35:57Альт
Спасибо. О том, что KP_IV можно задавать самому я из документации не уловил. Тогда пойду разбараться с сертификатами %) спасибо еще раз