Lockbox 3 — сброс, если он не инициализирован

я использую Windows 8 64-бит, Delphi XE7 и

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

введите здесь описание изображения введите здесь описание изображения

Генерация ключей

procedure TMainForm.Generate_RSA_Keys;
var
  Signatory1: TSignatory;
  codecRSA: TCodec;
  CryptographicLibrary1: TCryptographicLibrary;
  msPublic,msPrivate:TMemoryStream;
begin
  Application.ProcessMessages;
  //=================ini====================
  codecRSA:=TCodec.Create(nil);
  CryptographicLibrary1:=TCryptographicLibrary.Create(nil);
  Signatory1:=TSignatory.Create(nil);
  //=============TCodec===================
  codecRSA.CryptoLibrary  := CryptographicLibrary1;
  codecRSA.StreamCipherId := 'native.RSA';
  codecRSA.ChainModeId:= 'native.CBC';
  codecRSA.AsymetricKeySizeInBits := 1024;

  //====Signatory1=====================
  Signatory1.Codec :=codecRSA;

  //==========Save Keys==================
  msPublic:=TMemoryStream.Create;
  msPrivate:=TMemoryStream.Create;
  if Signatory1.GenerateKeys then
  begin
    Signatory1.StoreKeysToStream(msPublic,[partPublic]);
    Signatory1.StoreKeysToStream(msPrivate,[partPrivate]);
    msPublic.SaveToFile(Keypath + PublicKey);
    msPrivate.SaveToFile(Keypath + PrivateKey);
  end;
  msPublic.Free;
  msPrivate.Free;
  codecRSA.Free;
  CryptographicLibrary1.Free;
  Signatory1.Free;
end;

Шифровать

Call
  EncryptMemoOutput.Lines.Add(EncryptRSA_String(EncryptMemoInput.Text));

Процедура

function TMainForm.EncryptRSA_String(str:string):String;
var
  Signatory1: TSignatory;
  codecRSA: TCodec;
  CryptographicLibrary1: TCryptographicLibrary;
  ms:TMemoryStream;
  base64Ciphertext: string;
begin
  Result :='';
  //=================ini====================
  codecRSA:=TCodec.Create(nil);
  CryptographicLibrary1:=TCryptographicLibrary.Create(nil);
  Signatory1:=TSignatory.Create(nil);
  //=============TCodec===================
  codecRSA.CryptoLibrary  := CryptographicLibrary1;
  codecRSA.StreamCipherId := 'native.RSA';
  codecRSA.ChainModeId:= 'native.CBC';
  codecRSA.AsymetricKeySizeInBits := 1024;

  //====Signatory1=====================
  Signatory1.Codec :=codecRSA;
  //===Load public key=============
  ms:=TMemoryStream.Create;
  ms.LoadFromFile(Keypath + PublicKey);
  Signatory1.LoadKeysFromStream(ms,[partPublic]);
  codecRSA.EncryptString( str, base64Ciphertext);
  codecRSA.EncryptUtf8string( str, base64Ciphertext);
  Result := base64Ciphertext;
  //==free===========
  ms.Free;
  codecRSA.Free;
  CryptographicLibrary1.Free;
  Signatory1.Free;
end;

Расшифровать (исключение «TSimpleCodec.Init Reset when not initalized» выдает строку codec.DecryptString(str, base64Ciphertext); )

function  TMainForm.DecryptRSA_String(str:String):string ;
var
  ms:TMemoryStream;
  base64Ciphertext: String;
begin
  Result :='';
  codec.Reset;
  //===Load public key=============
  ms:=TMemoryStream.Create;
  ms.LoadFromFile(Keypath + PrivateKey);
  Signatory.LoadKeysFromStream(ms,[partPrivate]);
  codec.DecryptString(str, base64Ciphertext);
  Result := base64Ciphertext;

  //==free===========
  ms.Free;
end;

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

====================================================================

ОБНОВЛЕНИЕ ПН 10.08.2015

Когда я загружаю закрытые и открытые ключи через этот код, он работает

procedure TMainForm.Button6Click(Sender: TObject);
var
  Store: TStream;
  sRSAKeyFileName, Plain, a: String;
  sPlaintext, sReconstructedPlaintext: string;
  base64Ciphertext: String;
begin
  sRSAKeyFileName := 'C:\Users\Robin\Desktop\Dateien\Development\OpenSSL\Delphi\Win32\Debug\Keys\Lockbox.key';
  Store := TFileStream.Create( sRSAKeyFileName, fmOpenRead);
try
  Store.Position := 0;
  Signatory.LoadKeysFromStream( Store, [partPublic, partPrivate]);

  sPlainText := 'I love LockBox 3!';
  codec.EncryptString( sPlaintext, base64Ciphertext);
  codec.DecryptString( sReconstructedPlaintext, base64Ciphertext);
  ShowMessage(base64Ciphertext + #13#10 + sReconstructedPlaintext);
finally
  Store.Free
  end
end;

Когда я пытаюсь загрузить ключи serpatley, потому что я тоже сохранил их отдельно, они не работают

procedure TMainForm.btEncryptClick(Sender: TObject);
var
  g, f: TFileStream;
  s: String;
begin
  g := TFileStream.Create('C:\Users\Robin\Desktop\Dateien\Development\OpenSSL\Delphi\Win32\Debug\Keys\public.key', fmOpenRead); //openssl key
  g.Position := 0;
  Signatory.LoadKeysFromStream(g, [partPublic]);

  s := EncryptMemoInput.Text;
  codec.EncryptString(s, sCryped);
  EncryptMemoOutput.lines.Add(sCryped);

  codec.Reset;

  f := TFileStream.Create('C:\Users\Robin\Desktop\Dateien\Development\OpenSSL\Delphi\Win32\Debug\Keys\private.key', fmOpenRead);
  Signatory.LoadKeysFromStream(f, [partPrivate]);
  codec.EncryptString(sUncrypted, sCryped);
  ShowMessage(sUncrypted);


  g.Free;
  f.Free;
end;

Шифрование строки работает, шифрование не выдает «TSimpleCodec.Init — сброс, если он не инициализирован».

Возникает, когда я вызываю «codec.EncryptString(sUncrypted, sCryped);»

И когда я закрываю приложение, оно выдает «TSimpleCodec.Init — невозможно установить шифр во время кодирования/дешифрования».


person Hidden    schedule 04.08.2015    source источник
comment
E2037 Объявление «Зашифровать» отличается от предыдущего объявления: есть ли где-нибудь еще функция шифрования? Удерживая нажатой клавишу Ctrl, щелкните по нему, чтобы увидеть, куда это вас приведет.   -  person Jan Doggen    schedule 04.08.2015
comment
gist.github.com/Polymorphin/df3777292b199310962d   -  person Hidden    schedule 04.08.2015
comment
И я нашел эти 2 процедуры расшифровки gist.github.com/Polymorphin/47628e34b44e39802a71   -  person Hidden    schedule 04.08.2015
comment
Откуда вы скачали исходники?   -  person David Heffernan    schedule 04.08.2015
comment
@DavidHeffernan Что ж, проект переместился из кода Google в github, поэтому я скачал его с github. github.com/SeanBDurkin/tplockbox   -  person Hidden    schedule 04.08.2015
comment
Кажется, у него нет файла .dpr для демонстрации. Довольно странно на мой взгляд. Одна вещь, которую я не могу понять, заключается в том, что сообщение об ошибке, которое вы цитируете, называет Encrypt, но в коде вопроса нет ничего с этим именем. Как это может быть?   -  person David Heffernan    schedule 04.08.2015
comment
@David Это потому, что он задает 2 вопроса.   -  person Jan Doggen    schedule 04.08.2015
comment
Итак, главный вопрос в том, как исправить эту ошибку. Сброс, когда не инициализировано - я начал делать собственное тестовое приложение, потому что то, что в комплекте в архиве загрузки, не компилировалось и выдавало ошибку [ошибки DCC32] uDemoBlockModeCipher.pas (14): E2037 Объявление «Зашифровать» отличается от предыдущего объявления   -  person Hidden    schedule 04.08.2015
comment
В вашем коде не используется попытка/наконец и есть странный вызов ProcessMessages. Ваш код без необходимости использует потоки памяти вместо файловых потоков. Ты скопировал все это из кода сейфа? Лично я думаю, что был бы склонен компилировать настоящую демоверсию, но вы, похоже, не об этом спрашиваете.   -  person David Heffernan    schedule 04.08.2015
comment
Я пытался использовать файловые потоки, но у них нет каких-либо процедур загрузки/сохранения из/в файл... Единственный код, который я скопировал из официального кода блокировки, вставленный в две основные ссылки :)   -  person Hidden    schedule 04.08.2015
comment
Нет, это не так. Почему они? Просто создайте файловый поток и передайте его функции блокировки, которая ожидает поток. Это довольно сложная библиотека. Без действительно прочного знания основ языка и библиотек у вас будут проблемы.   -  person David Heffernan    schedule 04.08.2015
comment
Конечно, это сложная библиотека, но мы слишком много говорим не по теме. Я обновлю свой вопрос через несколько минут   -  person Hidden    schedule 04.08.2015
comment
Можете ли вы снова редактировать и уменьшить скриншоты хотя бы вдвое? Для начала вам следует никогда не публиковать снимки экрана с любым кодом — для этого и предназначена функция копирования/вставки вашей ОС. Скриншоты кода бесполезны — их трудно читать, код нельзя скопировать/вставить для тестирования, и они ничего не дают, кроме пустой траты места для людей, которым приходится платить за данные. Изображения следует использовать только в том случае, если нет альтернативы для объяснения проблемы, и ИМО ни в одном из них здесь не было необходимости.   -  person Ken White    schedule 05.08.2015


Ответы (1)


TurboPower LockBox 3 (v3.6.2.0 от https://github.com/SeanBDurkin/tplockbox) поставляется с демонстрационной программой, которая делает некоторые то, что вы пытаетесь сделать в этом вопросе. Обратитесь к программе "LockBox3_Demo.exe", вкладки "4. RSA - Генерация и хранение ключей" и "5. RSA - Подпись и проверка".

Я немного подчистил ваш опубликованный код в следующем листинге. У меня это работает (XE7, Win32, DEBUG). Вызовите Button1Click(), чтобы запустить циклический тест шифрования/дешифрования RSA.

Решение

uses TPLB3.CryptographicLibrary, TPLB3.Signatory, TPLB3.Codec,
     TPLB3.Asymetric;
{$R *.dfm}

procedure Generate_RSA_Keys( var msPublic, msPrivate: TMemoryStream);
var
  Signatory1: TSignatory;
  codecRSA: TCodec;
  CryptographicLibrary1: TCryptographicLibrary;
begin
  Application.ProcessMessages;
  //=================ini====================
  codecRSA:=TCodec.Create(nil);
  CryptographicLibrary1:=TCryptographicLibrary.Create(nil);
  Signatory1:=TSignatory.Create(nil);
  //=============TCodec===================
  codecRSA.CryptoLibrary  := CryptographicLibrary1;
  codecRSA.StreamCipherId := 'native.RSA';
  codecRSA.ChainModeId:= 'native.CBC';
  codecRSA.AsymetricKeySizeInBits := 1024;

  //====Signatory1=====================
  Signatory1.Codec :=codecRSA;

  //==========Save Keys==================
  msPublic:=TMemoryStream.Create;
  msPrivate:=TMemoryStream.Create;
  if Signatory1.GenerateKeys then
  begin
    Signatory1.StoreKeysToStream(msPublic,[partPublic]);
    Signatory1.StoreKeysToStream(msPrivate,[partPrivate]);
    msPublic.Position := 0;
    msPrivate.Position := 0;
  end;
  codecRSA.Free;
  CryptographicLibrary1.Free;
  Signatory1.Free;
end;


function EncryptRSA_String( const str:string; msPublic: TMemoryStream): string;
var
  Signatory1: TSignatory;
  codecRSA: TCodec;
  CryptographicLibrary1: TCryptographicLibrary;
  base64Ciphertext: string;
begin
  Result :='';
  //=================ini====================
  codecRSA :=TCodec.Create(nil);
  CryptographicLibrary1 := TCryptographicLibrary.Create(nil);
  Signatory1 :=TSignatory.Create(nil);
  //=============TCodec===================
  codecRSA.CryptoLibrary  := CryptographicLibrary1;
  codecRSA.StreamCipherId := 'native.RSA';
  codecRSA.ChainModeId:= 'native.CBC';
  codecRSA.AsymetricKeySizeInBits := 1024;

  //====Signatory1=====================
  Signatory1.Codec :=codecRSA;
  //===Load public key=============
  Signatory1.LoadKeysFromStream( msPublic, [partPublic]);
  msPublic.Position := 0;
  codecRSA.EncryptString( str, base64Ciphertext, TEncoding.UTF8);
  Result := base64Ciphertext;
  //==free===========
  codecRSA.Free;
  CryptographicLibrary1.Free;
  Signatory1.Free;
end;


function DecryptRSA_String( const base64Ciphertext: string; const msPublic, msPrivate: TMemoryStream): string ;
var
  Signatory1: TSignatory;
  codecRSA: TCodec;
  CryptographicLibrary1: TCryptographicLibrary;
begin
  Result :='';
  //=================ini====================
  codecRSA :=TCodec.Create(nil);
  CryptographicLibrary1 := TCryptographicLibrary.Create(nil);
  Signatory1 :=TSignatory.Create(nil);
  //=============TCodec===================
  codecRSA.CryptoLibrary  := CryptographicLibrary1;
  codecRSA.StreamCipherId := 'native.RSA';
  codecRSA.ChainModeId:= 'native.CBC';
  codecRSA.AsymetricKeySizeInBits := 1024;

  //====Signatory1=====================
  Signatory1.Codec :=codecRSA;
  Signatory1.LoadKeysFromStream( msPrivate,[partPrivate]);
  codecRSA.DecryptString( result, base64Ciphertext, TEncoding.UTF8);

  //==free===========
  codecRSA.Free;
  CryptographicLibrary1.Free;
  Signatory1.Free;
end;


procedure TForm27.Button1Click(Sender: TObject);
var
  msPublic,msPrivate: TMemoryStream;
  PlainText: string;
  CipherText: string;
  Recon: string;
begin
  PlainText := 'Some text';
  Generate_RSA_Keys( msPublic,msPrivate);
  CipherText := EncryptRSA_String( PlainText, msPublic);
  Recon      := DecryptRSA_String( CipherText, msPublic, msPrivate);
  msPublic.Free;
  msPrivate.Free;
  if Recon = PlainText then
      ShowMessage( 'PASS')
    else
      ShowMessage( 'FAIL')
end;

Что не так с кодом OP?

OP не показывает код внешнего уровня, который вызывал DecryptRSA_String(). Я предполагаю, что он вызвал DecryptRSA_String() с пустым фактическим значением параметра для str. Это вызовет исключение TSimpleCodec.Init Reset when not initalized.

person Sean B. Durkin    schedule 05.08.2015
comment
Спасибо за этот ответ, Шон, можете ли вы сказать мне, как мне загрузить открытый / закрытый ключ в -> Signatory1.LoadKeysFromStream, когда ключи существуют в виде файла на моем жестком диске и не генерируются самой моей программой? - person Hidden; 05.08.2015
comment
@Hidden: откройте файловый поток и загрузите его. - person Sean B. Durkin; 06.08.2015
comment
Ну теперь я не могу загрузить его в поток. Он всегда говорит об ошибке потока. stackoverflow.com/questions/31853481/ - person Hidden; 07.08.2015
comment
Похоже, Чадкопс и Уве Раабе ответили на ваш вопрос. - person Sean B. Durkin; 09.08.2015
comment
Когда я ему ответил, это не дало никакого эффекта - та же ошибка - person Hidden; 10.08.2015
comment
@Hidden: Можете ли вы опубликовать свой обновленный код, точное сообщение об ошибке и точку, в которой оно возникло. Без скриншотов, пожалуйста. - person Sean B. Durkin; 10.08.2015
comment
@Hidden: с асимметричными шифрами, такими как RSA, для шифрования требуется открытый ключ для шифрования и закрытый ключ для расшифровки. (Кроме того, для операции подписи требуется закрытый ключ, а для проверки требуется открытый ключ.) Когда вы загрузили закрытый ключ, он сдул открытый ключ, что означало, что кодек не был инициализирован для шифрования. Вероятно, вы предполагали, что второй Codec.EncryptString() будет Codec.DecryptString(). - person Sean B. Durkin; 12.08.2015