1

私は 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 初期化されていない場合のリセット」が 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 - 暗号化/復号化中に暗号を設定できません」がスローされます

4

1 に答える 1

1

TurboPower LockBox 3 ( https://github.com/SeanBDurkin/tplockboxの v3.6.2.0 )には、この質問でやろうとしていることを実行するデモ プログラムが付属しています。プログラム「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() を呼び出したと推測していますstrTSimpleCodec.Init Reset when not initalizedこれにより、その例外がスローされます。

于 2015-08-05T04:02:32.600 に答える