我找到了一个用于生成 RSA KeyPair 和加密/解密的简单单元。它适用于小字符串,但在较大的文本上我得到错误:错误长度。
可能是什么原因,这里是单位,单位 wcrypt2 你可以在这里下载
在德尔福 2010 上测试
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.