我发现了一个用于生成RSA KeyPair和加密/解密的简单单元。它在小字符串上工作正常但在较大的文本上我得到错误:Bad Length。
可能是什么原因,这是单位,你可以下载单位wcrypt2 here
在Delphi 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.
答案 0 :(得分:0)
答案 1 :(得分:0)
非对称加密将数据限制为小于密钥大小,OAEP等填充为42字节。
如果您必须使用非对称加密,则需要密钥对,请使用混合加密,这实质上是https所做的。请参阅Hybrid cryptosystem。
对于混合加密,基本上您可以创建随机对称加密密钥,使用非对称加密对对称密钥进行加密,使用对称密钥加密数据并将两个加密打包在一起。
为什么不想要对称加密?它更快,基本上处理任何数据大小? AES是加密的主力。