Форумчанин
Регистрация: 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;
Как с ними работать что-то понять не могу.
Желательно небольшой примерчик, заранее большое спасибо.
|