Delphi Windows Crypto Api错误长度
我找到了一个生成RSA密钥对和加密/解密的简单单元。它在小字符串上运行良好,但在较大的文本上我得到错误:错误的长度 原因可能是什么,这是你可以下载的装置,装置wcrypt2 在Delphi 2010上测试Delphi Windows Crypto Api错误长度,delphi,cryptoapi,Delphi,Cryptoapi,我找到了一个生成RSA密钥对和加密/解密的简单单元。它在小字符串上运行良好,但在较大的文本上我得到错误:错误的长度 原因可能是什么,这是你可以下载的装置,装置wcrypt2 在Delphi 2010上测试 unit Crypt_RSA; interface uses Windows, Classes, SysUtils, WCrypt2; function RSAGenerateKeys(var PrivateKey, PublicKey: String): Boolean; func
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.
简言之,C#表示明文长度远远超过密钥大小的1/2将导致错误。出于安全目的,大多数语言可能都是这样。对于较长的消息,请使用RSA传递对称加密(如AES)的密钥。非对称加密将数据限制在小于密钥大小的范围内,还有填充(如42字节的OAEP) 如果必须使用非对称加密(即需要密钥对),请使用混合加密,这基本上就是https所做的。看 对于混合加密,基本上创建一个随机对称加密密钥,使用非对称加密加密对称密钥,使用对称密钥加密数据,并将这两种加密打包在一起
你为什么不想要对称加密?它速度更快,基本上可以处理任意大小的数据?AES是加密的主力。我不想要对称加密我应该做什么您可以将密钥大小增加到2048位。但这仍然等于256个8位字符,请记住,大于该大小的1/2会抛出错误。因此,如果密钥大小为2048位,您可以发送大约128个字符长的消息。如果对多条消息重复使用密钥,则可能会影响安全性。我对常见做法的理解是,使用非对称建立连接并共享对称密钥,然后使用对称加密处理会话的其余部分,这会更快,而且不会受到纯文本大小限制的影响。会话不需要仅使用混合加密。虽然答案的基本内容是正确的,但有几个部分是错误的,如果有更正,这将是一个更好的答案。