Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 29.04.2019, 12:48   #1
denis76560
Форумчанин
 
Регистрация: 13.01.2010
Сообщений: 121
По умолчанию Вопрос по RSA классу.

Здравствуйте, нашел в интернете класс для работы с шифром RSA

Код:
unit rsaClass;

interface

uses
  Classes, Wcrypt2, Windows, SysUtils;

const
  EncodeTable: array[0..63] of AnsiChar = AnsiString('ABCDEFGHIJKLMNOPQRSTUVWXYZ') + AnsiString('abcdefghijklmnopqrstuvwxyz') + AnsiString('0123456789+/');
  DecodeTable: array[#0..#127] of Integer = (Byte('='), 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64, 64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64, 64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64);

type
  PPacket = ^TPacket;

  TPacket = packed record
    case Integer of
      0:
        (b0, b1, b2, b3: Byte);
      1:
        (i: Integer);
      2:
        (a: array[0..3] of Byte);
      3:
        (c: array[0..3] of AnsiChar);
  end;

{ TRSA }

type
  TRSA = class(TObject)
  private
    FPublicKey, FPrivateKey: ansistring;
    procedure EncodeStream(Input, Output: TStream);
    procedure DecodeStream(Input, Output: TStream);
    procedure EncodePacket(const Packet: TPacket; NumChars: Integer; OutBuf: PAnsiChar);
    function DecodePacket(InBuf: PAnsiChar; var nChars: Integer): TPacket;
  protected
  public
    property PrivateKey: string read FPrivateKey write FPrivateKey;
    property PublicKey: string read FPrivateKey write FPublicKey;
    function GenerateKeys(var PrivateKey, PublicKey: string): boolean;
    function Decrypt(source: ansistring): ansiString;
    function Encrypt(source: ansistring): ansiString;
  end;

implementation

function TRSA.Encrypt(source: ansistring): ansiString;
var
  KeyStream : TStringStream;
  DecodedKey: TmemoryStream;
  Stream: TMemoryStream;
  Base64: TStringStream;
  RSA: HCRYPTPROV;
  PublicKey: HCRYPTKEY;
  strlen: DWORD;
begin
  Stream := TMemoryStream.Create;
  KeyStream :=TStringStream.Create(Self.FPublicKey);
  DecodedKey :=TMemoryStream.Create;
  DecodeStream(KeyStream,DecodedKey);
  CryptAcquireContext(@RSA, nil, nil, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
  CryptImportKey(RSA, PByte(DecodedKey.Memory), DecodedKey.Size, 0, 0, @PublicKey);
  strlen := Length(source);
  CryptEncrypt(PublicKey, 0, true, 0, nil, @strlen, 0);
  Stream.SetSize(strlen);
  strlen := Length(source);
  CopyMemory(Stream.Memory, pointer(source), strlen);
  CryptEncrypt(PublicKey, 0, true, 0, PByte(Stream.Memory), @strlen, Stream.Size);
  Base64 := TStringStream.Create('');
  EncodeStream(Stream, Base64);
  Result := Base64.DataString;
  Base64.Free;
  Stream.Free;
  KeyStream.Free;
  DecodedKey.Free;
  CryptDestroyKey(PublicKey);
  CryptReleaseContext(RSA, 0);
end;

function TRSA.Decrypt(source: ansistring): ansiString;
var
  KeyStream : TStringStream;
  DecodedKey: TmemoryStream;
  Base64: TStringStream;
  Stream: TMemoryStream;
  RSA: HCRYPTPROV;
  PublicKey: HCRYPTKEY;
  strlen: DWORD;
begin
  Stream := TMemoryStream.Create;
  KeyStream :=TStringStream.Create(Self.FPrivateKey);
  DecodedKey :=TMemoryStream.Create;
  DecodeStream(KeyStream,DecodedKey);
  CryptAcquireContext(@RSA, nil, nil, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
  CryptImportKey(RSA, PByte(DecodedKey.Memory),DecodedKey.Size, 0, 0, @PublicKey);
  Base64 := TStringStream.Create(source);
  DecodeStream(Base64, Stream);
  Base64.Size := 0;
  strlen := Stream.Size;
  CryptDecrypt(PublicKey, 0, true, 0, PByte(Stream.Memory), @strlen);
  Stream.SetSize(strlen);
  Stream.SaveToStream(Base64);
  Result := Base64.DataString;
  Base64.Free;
  Stream.Free;
  KeyStream.Free;
  CryptDestroyKey(PublicKey);
  CryptReleaseContext(RSA, 0);
end;


  function ReadInput: Integer;
  var
    WhiteFound, EndReached: Boolean;
    CntRead, Idx, IdxEnd: Integer;
  begin
    IdxEnd := 0;
    repeat
      WhiteFound := False;
      CntRead := Input.Read(InBuf[IdxEnd], (SizeOf(InBuf) - IdxEnd));
      EndReached := CntRead < (SizeOf(InBuf) - IdxEnd);
      Idx := IdxEnd;
      IdxEnd := CntRead + IdxEnd;
      while (Idx < IdxEnd) do
      begin
        if not (InBuf[Idx] in ['0'..'9', 'A'..'Z', 'a'..'z', '+', '/', '=']) then
        begin
          Dec(IdxEnd);
          if Idx < IdxEnd then
            Move(InBuf[Idx + 1], InBuf[Idx], IdxEnd - Idx);
          WhiteFound := True;
        end
        else
          Inc(Idx);
      end;
    until (not WhiteFound) or (EndReached);
    Result := IdxEnd;
  end;

begin
  repeat
    SkipWhite;
    BytesRead := ReadInput;
    InBufPtr := InBuf;
    OutBufPtr := @OutBuf;
    I := 0;
    while I < BytesRead do
    begin
      Packet := DecodePacket(InBufPtr, J);
      K := 0;
      while J > 0 do
      begin
        OutBufPtr^ := AnsiChar(Packet.a[K]);
        Inc(OutBufPtr);
        Dec(J);
        Inc(K);
      end;
      Inc(InBufPtr, 4);
      Inc(I, 4);
    end;
    Output.Write(OutBuf, OutBufPtr - PAnsiChar(@OutBuf));
  until BytesRead = 0;
end;

function TRsa.GenerateKeys(var PrivateKey, PublicKey: string): Boolean;
const
  RSA1024BIT_KEY = $04000000;

var
  RSA: HCRYPTPROV;
  HKeyPair: HCRYPTKEY;
  Pair: TMemoryStream;
  Base64: TStringStream;
  buflen: DWORD;

  function SetKey(BlobDef: Cardinal; var Key: string): Boolean;
  begin
    Result := Bool(CryptExportKey(HKeyPair, 0, BlobDef, 0, nil, @buflen));
    if Result then
    begin
      Pair.SetSize(buflen);
      Result := Bool(CryptExportKey(HKeyPair, 0, BlobDef, 0, PByte(Pair.Memory), @buflen));
    end;
    Base64 := TStringStream.Create('');
    EncodeStream(Pair, Base64);
    Key := Base64.DataString;
    Pair.Seek(0, soBeginning);
    Base64.Free;
  end;

begin
  Pair := TMemoryStream.Create;

  Result := Bool(CryptAcquireContext(@RSA, nil, nil, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT));
  if Result then
    Result := Bool(CryptGenKey(RSA, AT_KEYEXCHANGE, RSA1024BIT_KEY or CRYPT_EXPORTABLE, @HKeyPair));

  if Result then
    Result := SetKey(PRIVATEKEYBLOB, PrivateKey);
  if Result then
    Result := SetKey(PUBLICKEYBLOB, PublicKey);

  CryptDestroyKey(HKeyPair);
  CryptReleaseContext(RSA, 0);
  FreeAndNil(Pair);
end;

end.
Подскажите пожалуйста как с ним работать.

Вроде нужных функций всего три
Код:
    function GenerateKeys(var PrivateKey, PublicKey: string): boolean;
    function Decrypt(source: ansistring): ansiString;
    function Encrypt(source: ansistring): ansiString;
Как с ними работать что-то понять не могу.
Желательно небольшой примерчик, заранее большое спасибо.
denis76560 вне форума Ответить с цитированием
Старый 29.04.2019, 13:15   #2
denis76560
Форумчанин
 
Регистрация: 13.01.2010
Сообщений: 121
По умолчанию

Разобрался сам. Кому нужно
Код:
      if RSA.GenerateKeys(PrivateKey, PublicKey) then
  begin
   CryptedMessage:=RSA.Encrypt('123');
   DeCryptedMessage:=RSA.Decrypt(CryptedMessage);
  ShowMessage(CryptedMessage);
  ShowMessage(DeCryptedMessage);
end;
StrToFile('key.txt', RSA.PrivateKey);
      RSA.Free;
Осталась единственная проблема, когда сохраняю ключи в файл, он оказывается пуст, прошу помочь с этим
denis76560 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Вопрос по классу Scanner. Gentanto Общие вопросы по Java, Java SE, Kotlin 5 19.06.2017 10:12
Вопрос по классу-делегату и принимаемыми им параметрами BadCats C# (си шарп) 3 13.04.2016 10:24
Обращение к базовому классу ACE Valery Общие вопросы C/C++ 17 02.01.2013 18:04
Как передать обьетк классу??? KoctR Общие вопросы C/C++ 11 25.03.2012 17:22
Параметр классу? Непонятный с++. jojahti Общие вопросы C/C++ 4 16.10.2009 08:55