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 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 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
|
unit Crypt_RSA;
interface
uses
Windows, Classes, SysUtils, WCrypt2;
function RSAGenerateKeys(var PrivateKey, PublicKey: String): Boolean;
function RSAEncrypt(Source, Key: String): String;
function RSADecrypt(Source, Key: String): String;
implementation
function RSAGenerateKeys(var PrivateKey, PublicKey: String): Boolean;
const
RSA1024BIT_KEY = $04000000;
var
RSA: HCRYPTPROV;
HKeyPair: HCRYPTKEY;
Pair: 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;
Key := Pair.ReadString(buflen);
Pair.Seek(0, soBeginning);
end;
begin
Pair := TStringStream.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;
function RSAEncrypt(Source, Key: String): String;
var
KeyPair: TStringStream;
RSA: HCRYPTPROV;
HPair: HCRYPTKEY;
DDataSize, EDataSize: DWORD;
begin
Result := '';
KeyPair := TStringStream.Create(Key);
if CryptAcquireContext(@RSA, nil, nil, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT) then
try
if CryptImportKey(RSA, PByte(KeyPair.Memory), KeyPair.Size, 0, 0, @HPair) then
try
EDataSize := SizeOf(Source);
if CryptEncrypt(HPair, 0, true, 0, nil, @EDataSize, 0) then
begin
Result := Source;
SetLength(Result, EDataSize);
DDataSize := Length(Source) * SizeOf(Char);
if not(CryptEncrypt(HPair, 0, True, 0, PByte(PChar(Result)), @DDataSize, EDataSize)) then
Result := '';
end;
finally
CryptDestroyKey(HPair);
end;
finally
CryptReleaseContext(RSA, 0);
end;
FreeAndNil(KeyPair);
end;
function RSADecrypt(Source, Key: String): String;
var
KeyPair: TStringStream;
RSA: HCRYPTPROV;
HPair: HCRYPTKEY;
EDataSize: DWORD;
begin
KeyPair := TStringStream.Create(Key);
Result := '';
if CryptAcquireContext(@RSA, nil, nil, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT) then
try
if CryptImportKey(RSA, PByte(KeyPair.Memory), KeyPair.Size, 0, 0, @HPair) then
try
Result := Source;
EDataSize := Length(Result);
if not Bool(CryptDecrypt(HPair, 0, True, 0, PByte(PChar(Result)), @EDataSize)) then
EDataSize := 0;
SetLength(Result, EDataSize div SizeOf(Char));
finally
CryptDestroyKey(HPair);
end;
finally
CryptReleaseContext(RSA, 0);
end;
FreeAndNil(KeyPair);
end;
end. |
Partager