📄 lbrsa.pas
字号:
Max := Length;
pInput := Input;
{ check for sequence }
Tag := GetASN1StructNum(pInput, Max);
GetASN1StructLen(pInput, Max);
if (Tag <> ASN1_TYPE_SEQUENCE) then
raise Exception.Create(sRSAKeyBadKey);
ParseASN1(pInput, Max, FModulus);
ParseASN1(pInput, Max, FExponent);
Result := (Max = 0);
end;
{ == TLbRSA ================================================================ }
constructor TLbRSA.Create(AOwner : TComponent);
{ initialize }
begin
inherited Create(AOwner);
FPrivateKey := TLbRSAKey.Create(FKeySize);
FPublicKey := TLbRSAKey.Create(FKeySize);
FPrimeTestIterations := cDefIterations;
end;
{ -------------------------------------------------------------------------- }
destructor TLbRSA.Destroy;
{ finalize }
begin
FPrivateKey.Free;
FPublicKey.Free;
inherited Destroy;
end;
{ -------------------------------------------------------------------------- }
procedure TLbRSA.DecryptFile(const InFile, OutFile : string);
{ decrypt file data with RSA private key }
begin
RSAEncryptFile(InFile, OutFile, FPrivateKey, False);
end;
{ -------------------------------------------------------------------------- }
procedure TLbRSA.DecryptStream(InStream , OutStream : TStream);
{ decrypt stream data with RSA private key }
begin
RSAEncryptStream(InStream, OutStream, FPrivateKey, False);
end;
{ -------------------------------------------------------------------------- }
function TLbRSA.DecryptString(const InString : string) : string;
{ decrypt string data with RSA private key }
begin
Result := RSAEncryptString(InString, FPrivateKey, False);
end;
{ -------------------------------------------------------------------------- }
procedure TLbRSA.EncryptFile(const InFile, OutFile : string);
{ encrypt file data with RSA public key }
begin
RSAEncryptFile(InFile, OutFile, FPublicKey, True);
end;
{ -------------------------------------------------------------------------- }
procedure TLbRSA.EncryptStream(InStream, OutStream : TStream);
{ encrypt stream data with RSA public key }
begin
RSAEncryptStream(InStream, OutStream, FPublicKey, True);
end;
{ -------------------------------------------------------------------------- }
function TLbRSA.EncryptString(const InString : string) : string;
{ encrypt string data with RSA public key }
begin
Result := RSAEncryptString(InString, FPublicKey, True);
end;
{ -------------------------------------------------------------------------- }
procedure TLbRSA.GenerateKeyPair;
{ generate RSA public/private key pair }
begin
if Assigned(FPrivateKey) then
FPrivateKey.Free;
if Assigned(FPublicKey) then
FPublicKey.Free;
try
GenerateRSAKeysEx(FPrivateKey, FPublicKey, FKeySize,
FPrimeTestIterations, RSACallback);
except
raise Exception.Create(sRSAKeyPairErr);
end;
end;
{ -------------------------------------------------------------------------- }
function TLbRSA.OutBufSizeNeeded(InBufSize : Cardinal) : Cardinal;
{ return size of ciphertext buffer required to encrypt plaintext InBuf }
var
BlkCount : Cardinal;
begin
BlkCount := InBufSize div cRSAPlainBlockSize[FKeySize]; {!!.02}
if (InBufSize mod cRSAPlainBlockSize[FKeySize]) > 0 then {!!.02}
Inc(BlkCount);
Result := BlkCount * cRSACipherBlockSize[FKeySize]; {!!.02}
end;
{ -------------------------------------------------------------------------- }
procedure TLbRSA.RSACallback(var Abort : Boolean);
{ pass callback on via OnProgress event }
begin
Abort := False;
if Assigned(FOnProgress) then
FOnProgress(Self, Abort);
end;
{ -------------------------------------------------------------------------- }
{!!.02}
procedure TLbRSA.SetKeySize(Value : TLbAsymKeySize);
begin
FKeySize := Value;
FPublicKey.KeySize := FKeySize;
FPrivateKey.KeySize := FKeySize;
end;
{ == TLbRSASSA ============================================================= }
constructor TLbRSASSA.Create(AOwner : TComponent);
{ initialize }
begin
inherited Create(AOwner);
FPrivateKey := TLbRSAKey.Create(FKeySize);
FPublicKey := TLbRSAKey.Create(FKeySize);
FSignature := TLbBigInt.Create(cLbAsymKeyBytes[FKeySize]);
FHashMethod := cDefHashMethod;
FPrimeTestIterations := cDefIterations;
end;
{ -------------------------------------------------------------------------- }
destructor TLbRSASSA.Destroy;
{ finalize }
begin
FPrivateKey.Free;
FPublicKey.Free;
FSignature.Free;
inherited Destroy;
end;
{ -------------------------------------------------------------------------- }
procedure TLbRSASSA.DoGetSignature;
{ fire OnGetSignature event to obtain RSA signature }
var
SigBlock : TRSASignatureBlock;
begin
if Assigned(FOnGetSignature) then begin
FillChar(SigBlock, SizeOf(SigBlock), #0);
FOnGetSignature(Self, SigBlock);
FSignature.CopyBuffer(SigBlock, cLbAsymKeyBytes[FKeySize]); {!!.02}
FSignature.Trim;
end;
end;
{ -------------------------------------------------------------------------- }
procedure TLbRSASSA.GenerateKeyPair;
{ generate RSA public/private key pair }
begin
if Assigned(FPrivateKey) then
FPrivateKey.Free;
if Assigned(FPublicKey) then
FPublicKey.Free;
GenerateRSAKeysEx(FPrivateKey, FPublicKey, FKeySize, FPrimeTestIterations,
RSACallback);
end;
{ -------------------------------------------------------------------------- }
procedure TLbRSASSA.EncryptHash(const HashDigest; DigestLen : Cardinal);
{ encrypt message digest into signature }
begin
if (FPrivateKey.Modulus.Size = 0) then {!!.02}
raise Exception.Create(sRSAPrivateKeyErr);
FSignature.CopyBuffer(HashDigest, DigestLen);
RSAEncryptBigInt(FSignature, FPrivateKey, bt01, True); {!!.02}
end;
{ -------------------------------------------------------------------------- }
procedure TLbRSASSA.DecryptHash(var HashDigest; DigestLen : Cardinal);
{ decrypt signature into message digest }
var
biBlock : TLbBigInt;
begin
if (FPublicKey.Modulus.Size = 0) then {!!.02}
raise Exception.Create(sRSAPublicKeyErr);
biBlock := TLbBigInt.Create(cLbAsymKeyBytes[FKeySize]);
try
DoGetSignature;
biBlock.Copy(FSignature);
RSAEncryptBigInt(biBlock, FPublicKey, bt01, False); {!!.02}
FillChar(HashDigest, DigestLen, #0);
if biBlock.Size < Integer(DigestLen) then {!!.05}
biBlock.ToBuffer(HashDigest, biBlock.Size)
else
biBlock.ToBuffer(HashDigest, DigestLen);
except
{ just swallow the error, signature comparison will fail benignly }
end;
biBlock.Free;
end;
{ -------------------------------------------------------------------------- }
procedure TLbRSASSA.SignBuffer(const Buf; BufLen : Cardinal);
{ generate RSA signature of buffer data }
var
MD5Digest : TMD5Digest;
SHA1Digest : TSHA1Digest;
begin
case FHashMethod of
hmMD5 :
begin
HashMD5(MD5Digest, Buf, BufLen);
EncryptHash(MD5Digest, SizeOf(MD5Digest));
end;
hmSHA1 :
begin
HashSHA1(SHA1Digest, Buf, BufLen);
EncryptHash(SHA1Digest, SizeOf(SHA1Digest));
end;
end;
end;
{ -------------------------------------------------------------------------- }
procedure TLbRSASSA.SignFile(const AFileName : string);
{ generate RSA signature of file data }
var
MD5Digest : TMD5Digest;
SHA1Digest : TSHA1Digest;
begin
case FHashMethod of
hmMD5 :
begin
FileHashMD5(MD5Digest, AFileName);
EncryptHash(MD5Digest, SizeOf(MD5Digest));
end;
hmSHA1 :
begin
FileHashSHA1(SHA1Digest, AFileName);
EncryptHash(SHA1Digest, SizeOf(SHA1Digest));
end;
end;
end;
{ -------------------------------------------------------------------------- }
procedure TLbRSASSA.SignStream(AStream : TStream);
{ generate RSA signature of stream data }
var
MD5Digest : TMD5Digest;
SHA1Digest : TSHA1Digest;
begin
case FHashMethod of
hmMD5 :
begin
StreamHashMD5(MD5Digest, AStream);
EncryptHash(MD5Digest, SizeOf(MD5Digest));
end;
hmSHA1 :
begin
StreamHashSHA1(SHA1Digest, AStream);
EncryptHash(SHA1Digest, SizeOf(SHA1Digest));
end;
end;
end;
{ -------------------------------------------------------------------------- }
procedure TLbRSASSA.SignString(const AStr : string);
{ generate RSA signature of string data }
var
MD5Digest : TMD5Digest;
SHA1Digest : TSHA1Digest;
begin
case FHashMethod of
hmMD5 :
begin
StringHashMD5(MD5Digest, AStr);
EncryptHash(MD5Digest, SizeOf(MD5Digest));
end;
hmSHA1 :
begin
StringHashSHA1(SHA1Digest, AStr);
EncryptHash(SHA1Digest, SizeOf(SHA1Digest));
end;
end;
end;
{ -------------------------------------------------------------------------- }
function TLbRSASSA.VerifyBuffer(const Buf; BufLen : Cardinal) : Boolean;
{ verify RSA signature agrees with buffer data }
var
MD5Digest1 : TMD5Digest;
MD5Digest2 : TMD5Digest;
SHA1Digest1 : TSHA1Digest;
SHA1Digest2 : TSHA1Digest;
begin
case FHashMethod of
hmMD5 :
begin
DecryptHash(MD5Digest1, SizeOf(TMD5Digest));
HashMD5(MD5Digest2, Buf, BufLen);
Result := CompareBuffers(MD5Digest1, MD5Digest2, SizeOf(TMD5Digest));
end;
hmSHA1 :
begin
DecryptHash(SHA1Digest1, SizeOf(TSHA1Digest));
HashSHA1(SHA1Digest2, Buf, BufLen);
Result := CompareBuffers(SHA1Digest1, SHA1Digest2, SizeOf(TSHA1Digest));
end;
else
Result := False;
end;
end;
{ -------------------------------------------------------------------------- }
function TLbRSASSA.VerifyFile(const AFileName : string) : Boolean;
{ verify RSA signature agrees with file data }
var
MD5Digest1 : TMD5Digest;
MD5Digest2 : TMD5Digest;
SHA1Digest1 : TSHA1Digest;
SHA1Digest2 : TSHA1Digest;
begin
case FHashMethod of
hmMD5 :
begin
DecryptHash(MD5Digest1, SizeOf(TMD5Digest));
FileHashMD5(MD5Digest2, AFileName);
Result := CompareBuffers(MD5Digest1, MD5Digest2, SizeOf(TMD5Digest));
end;
hmSHA1 :
begin
DecryptHash(SHA1Digest1, SizeOf(TSHA1Digest));
FileHashSHA1(SHA1Digest2, AFileName);
Result := CompareBuffers(SHA1Digest1, SHA1Digest2, SizeOf(TSHA1Digest));
end;
else
Result := False;
end;
end;
{ -------------------------------------------------------------------------- }
function TLbRSASSA.VerifyStream(AStream : TStream) : Boolean;
{ verify RSA signature agrees with stream data }
var
MD5Digest1 : TMD5Digest;
MD5Digest2 : TMD5Digest;
SHA1Digest1 : TSHA1Digest;
SHA1Digest2 : TSHA1Digest;
begin
case FHashMethod of
hmMD5 :
begin
DecryptHash(MD5Digest1, SizeOf(TMD5Digest));
StreamHashMD5(MD5Digest2, AStream);
Result := CompareBuffers(MD5Digest1, MD5Digest2, SizeOf(TMD5Digest));
end;
hmSHA1 :
begin
DecryptHash(SHA1Digest1, SizeOf(TSHA1Digest));
StreamHashSHA1(SHA1Digest2, AStream);
Result := CompareBuffers(SHA1Digest1, SHA1Digest2, SizeOf(TSHA1Digest));
end;
else
Result := False;
end;
end;
{ -------------------------------------------------------------------------- }
function TLbRSASSA.VerifyString(const AStr : string) : Boolean;
{ verify RSA signature agrees with string data }
var
MD5Digest1 : TMD5Digest;
MD5Digest2 : TMD5Digest;
SHA1Digest1 : TSHA1Digest;
SHA1Digest2 : TSHA1Digest;
begin
case FHashMethod of
hmMD5 :
begin
DecryptHash(MD5Digest1, SizeOf(TMD5Digest));
StringHashMD5(MD5Digest2, AStr);
Result := CompareBuffers(MD5Digest1, MD5Digest2, SizeOf(TMD5Digest));
end;
hmSHA1 :
begin
DecryptHash(SHA1Digest1, SizeOf(TSHA1Digest));
StringHashSHA1(SHA1Digest2, AStr);
Result := CompareBuffers(SHA1Digest1, SHA1Digest2, SizeOf(TSHA1Digest));
end;
else
Result := False;
end;
end;
{ -------------------------------------------------------------------------- }
procedure TLbRSASSA.RSACallback(var Abort : Boolean);
{ pass callback on via OnProgress event }
begin
Abort := False;
if Assigned(FOnProgress) then
FOnProgress(Self, Abort);
end;
{ -------------------------------------------------------------------------- }
{!!.02}
procedure TLbRSASSA.SetKeySize(Value : TLbAsymKeySize);
begin
if (Ord(Value) < Ord(aks256)) then begin
if (csDesigning in ComponentState) then
FKeySize := aks256
else
raise Exception.Create('Invalid key size for RSASSA');
end else
FKeySize := Value;
FPublicKey.KeySize := FKeySize;
FPrivateKey.KeySize := FKeySize;
FSignature.Free;
FSignature := TLbBigInt.Create(cLbAsymKeyBytes[FKeySize]);
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -