📄 lbrsa.pas
字号:
repeat
{ p , q = random primes }
repeat
p.RandomPrime(PrimeTestIterations);
{ check for abort }
if Assigned(Callback) then
Callback(Abort);
if Abort then
Exit;
q.RandomPrime(PrimeTestIterations);
{ check for abort }
if Assigned(Callback) then
Callback(Abort);
if Abort then
Exit;
until (p.Compare(q) <> 0);
{ n = pq }
n.Copy(p);
n.Multiply(q);
{ p1q1 = (p-1)(q-1) }
p.SubtractByte($01);
q.SubtractByte($01);
p1q1.Copy(p);
p1q1.Multiply(q);
{ e = randomly chosen simple prime > 3 }
e.RandomSimplePrime;
{ d = inverse(e) mod (p-1)(q-1) }
d.Copy(e);
until d.ModInv(p1q1);
{ assign n and d to private key }
PrivateKey.Modulus.Copy(n);
PrivateKey.Exponent.Copy(d);
{ assign n and e to public key }
PublicKey.Modulus.Copy(n);
PublicKey.Exponent.Copy(e);
finally
p1q1.Free;
d.Free;
e.Free;
n.Free;
p.Free;
q.Free;
end;
end;
{ -------------------------------------------------------------------------- }
{!!.02}
function EncryptRSAEx(PublicKey : TLbRSAKey;
pInBlock, pOutBlock : PByteArray;
InDataSize : Integer) : Longint;
{ IMPORTANT: verify block sizes before calling this routine }
var
biBlock : TLbBigInt;
OutSize : DWord;
begin
OutSize := cRSACipherBlockSize[PublicKey.KeySize];
biBlock := TLbBigInt.Create(OutSize);
try
biBlock.CopyBuffer(pInBlock^, InDataSize);
RSAEncryptBigInt(biBlock, PublicKey, bt02, True);
if Integer(OutSize) < biBlock.Size then {!!.05}
raise Exception.Create('OutBlock size too small');
biBlock.ToBuffer(pOutBlock^, biBlock.Size);
finally
Result := biBlock.Size;
biBlock.Free;
end;
end;
{ -------------------------------------------------------------------------- }
{!!.02}
function DecryptRSAEx(PrivateKey : TLbRSAKey;
pInBlock, pOutBlock : PByteArray) : Longint;
{ IMPORTANT: verify block sizes before calling this routine }
var
biBlock : TLbBigInt;
InSize, OutSize : DWord;
begin
InSize := cRSACipherBlockSize[PrivateKey.KeySize];
OutSize := cRSAPlainBlockSize[PrivateKey.KeySize];
biBlock := TLbBigInt.Create(InSize);
try
biBlock.CopyBuffer(pInBlock^, InSize);
RSAEncryptBigInt(biBlock, PrivateKey, bt02, False);
if Integer(OutSize) < biBlock.Size then {!!.05}
raise Exception.Create('OutBlock size too small');
biBlock.ToBuffer(pOutBlock^, biBlock.Size);
finally
Result := biBlock.Size;
biBlock.Free;
end;
end;
{ -------------------------------------------------------------------------- }
{!!.02}
function EncryptRSA128(PublicKey : TLbRSAKey; const InBlock : TRSAPlainBlock128;
var OutBlock : TRSACipherBlock128) : Longint;
{ encrypt plaintext block with 128-bit RSA public key }
begin
if (PublicKey.KeySize <> aks128) then
raise Exception.Create(sRSABlockSize128Err);
Result := EncryptRSAEx(PublicKey, @InBlock, @OutBlock, SizeOf(InBlock));
end;
{ -------------------------------------------------------------------------- }
{!!.02}
function DecryptRSA128(PrivateKey : TLbRSAKey; const InBlock : TRSACipherBlock128;
var OutBlock : TRSAPlainBlock128) : Longint;
{ decrypt ciphertext block with 128-bit RSA private key }
begin
if (PrivateKey.KeySize <> aks128) then
raise Exception.Create(sRSABlockSize128Err);
Result := DecryptRSAEx(PrivateKey, @InBlock, @OutBlock);
end;
{ -------------------------------------------------------------------------- }
{!!.02}
function EncryptRSA256(PublicKey : TLbRSAKey; const InBlock : TRSAPlainBlock256;
var OutBlock : TRSACipherBlock256) : Longint;
{ encrypt plaintext block with 256-bit RSA public key }
begin
if (PublicKey.KeySize <> aks256) then
raise Exception.Create(sRSABlockSize256Err);
Result := EncryptRSAEx(PublicKey, @InBlock, @OutBlock, SizeOf(InBlock));
end;
{ -------------------------------------------------------------------------- }
{!!.02}
function DecryptRSA256(PrivateKey : TLbRSAKey; const InBlock : TRSACipherBlock256;
var OutBlock : TRSAPlainBlock256) : Longint;
{ decrypt ciphertext block with 256-bit RSA private key }
begin
if (PrivateKey.KeySize <> aks256) then
raise Exception.Create(sRSABlockSize256Err);
Result := DecryptRSAEx(PrivateKey, @InBlock, @OutBlock);
end;
{ -------------------------------------------------------------------------- }
{!!.02}
function EncryptRSA512(PublicKey : TLbRSAKey; const InBlock : TRSAPlainBlock512;
var OutBlock : TRSACipherBlock512) : Longint;
{ encrypt plaintext block with 512-bit RSA public key }
begin
if (PublicKey.KeySize <> aks512) then
raise Exception.Create(sRSABlockSize512Err);
Result := EncryptRSAEx(PublicKey, @InBlock, @OutBlock, SizeOf(InBlock));
end;
{ -------------------------------------------------------------------------- }
{!!.02}
function DecryptRSA512(PrivateKey : TLbRSAKey; const InBlock : TRSACipherBlock512;
var OutBlock : TRSAPlainBlock512) : Longint;
{ decrypt ciphertext block with 512-bit RSA private key }
begin
if (PrivateKey.KeySize <> aks512) then
raise Exception.Create(sRSABlockSize512Err);
Result := DecryptRSAEx(PrivateKey, @InBlock, @OutBlock);
end;
{ -------------------------------------------------------------------------- }
{!!.02}
function EncryptRSA768(PublicKey : TLbRSAKey; const InBlock : TRSAPlainBlock768;
var OutBlock : TRSACipherBlock768) : Longint;
{ encrypt plaintext block with 768-bit RSA public key }
begin
if (PublicKey.KeySize <> aks768) then
raise Exception.Create(sRSABlockSize768Err);
Result := EncryptRSAEx(PublicKey, @InBlock, @OutBlock, SizeOf(InBlock));
end;
{ -------------------------------------------------------------------------- }
{!!.02}
function DecryptRSA768(PrivateKey : TLbRSAKey; const InBlock : TRSACipherBlock768;
var OutBlock : TRSAPlainBlock768) : Longint;
{ decrypt ciphertext block with 768-bit RSA private key }
begin
if (PrivateKey.KeySize <> aks768) then
raise Exception.Create(sRSABlockSize768Err);
Result := DecryptRSAEx(PrivateKey, @InBlock, @OutBlock);
end;
{ -------------------------------------------------------------------------- }
{!!.02}
function EncryptRSA1024(PublicKey : TLbRSAKey; const InBlock : TRSAPlainBlock1024;
var OutBlock : TRSACipherBlock1024) : Longint;
{ encrypt plaintext block with 1024-bit RSA public key }
begin
if (PublicKey.KeySize <> aks1024) then
raise Exception.Create(sRSABlockSize1024Err);
Result := EncryptRSAEx(PublicKey, @InBlock, @OutBlock, SizeOf(InBlock));
end;
{ -------------------------------------------------------------------------- }
{!!.02}
function DecryptRSA1024(PrivateKey : TLbRSAKey; const InBlock : TRSACipherBlock1024;
var OutBlock : TRSAPlainBlock1024) : Longint;
{ decrypt ciphertext block with 1024-bit RSA private key }
begin
if (PrivateKey.KeySize <> aks1024) then
raise Exception.Create(sRSABlockSize1024Err);
Result := DecryptRSAEx(PrivateKey, @InBlock, @OutBlock);
end;
{ -------------------------------------------------------------------------- }
function EncryptRSA(PublicKey : TLbRSAKey; const InBlock : TRSAPlainBlock;
var OutBlock : TRSACipherBlock) : Longint;
{ encrypt plaintext block with 512-bit RSA public key }
begin
Result := EncryptRSA512(PublicKey, InBlock, OutBlock); {!!.02}
end;
{ -------------------------------------------------------------------------- }
function DecryptRSA(PrivateKey : TLbRSAKey; const InBlock : TRSACipherBlock;
var OutBlock : TRSAPlainBlock) : Longint;
{ decrypt ciphertext block with 512-bit RSA private key }
begin
Result := DecryptRSA512(PrivateKey, InBlock, OutBlock); {!!.02}
end;
{ -------------------------------------------------------------------------- }
procedure RSAEncryptFile(const InFile, OutFile : string;
Key : TLbRSAKey; Encrypt : Boolean);
{ encrypt/decrypt file data with RSA key }
var
InStream, OutStream : TStream;
begin
InStream := TFileStream.Create(InFile, fmOpenRead or fmShareDenyWrite);
try
OutStream := TFileStream.Create(OutFile, fmCreate);
try
RSAEncryptStream(InStream, OutStream, Key, Encrypt);
finally
OutStream.Free;
end;
finally
InStream.Free;
end;
end;
{ -------------------------------------------------------------------------- }
procedure RSAEncryptStream(InStream, OutStream : TStream;
Key : TLbRSAKey; Encrypt : Boolean);
{ encrypt/decrypt stream data with RSA key }
var
InBlkCount : Integer;
InBlkSize, OutBlkSize : Integer;
PlainBlockSize, CipherBlockSize : Integer;
i : Integer;
pInBlk, pOutBlk : Pointer;
PlainBlock, CipherBlock : TRSACipherBlock1024;
begin
PlainBlockSize := cRSAPlainBlockSize[Key.KeySize];
CipherBlockSize := cRSACipherBlockSize[Key.KeySize];
if Encrypt then begin
pInBlk := @PlainBlock;
pOutBlk := @CipherBlock;
InBlkSize := PlainBlockSize;
OutBlkSize := CipherBlockSize;
end else begin
pInBlk := @CipherBlock;
pOutBlk := @PlainBlock;
InBlkSize := CipherBlockSize;
OutBlkSize := PlainBlockSize;
end;
InBlkCount := InStream.Size div InBlkSize;
if (InStream.Size mod InBlkSize) > 0 then
Inc(InBlkCount);
{ process all except the last block }
for i := 1 to (InBlkCount - 1) do begin
InStream.Read(pInBlk^, InBlkSize);
if Encrypt then
EncryptRSAEx(Key, pInBlk, pOutBlk, InBlkSize)
else
DecryptRSAEx(Key, pInBlk, pOutBlk);
OutStream.Write(pOutBlk^, OutBlkSize);
end;
{ process the last block }
i := InStream.Read(pInBlk^, InBlkSize);
if Encrypt then
i := EncryptRSAEx(Key, pInBlk, pOutBlk, i)
else
i := DecryptRSAEx(Key, pInBlk, pOutBlk);
OutStream.Write(pOutBlk^, i);
end;
{ -------------------------------------------------------------------------- }
function RSAEncryptString(const InString : string;
Key : TLbRSAKey; Encrypt : Boolean) : string;
{ encrypt/decrypt string data with RSA key }
var
InStream : TMemoryStream;
OutStream : TMemoryStream;
WorkStream : TMemoryStream;
begin
InStream := TMemoryStream.Create;
OutStream := TMemoryStream.Create;
WorkStream := TMemoryStream.Create;
InStream.Write(InString[1], Length(InString));
InStream.Position := 0;
if Encrypt then begin
RSAEncryptStream(InStream, WorkStream, Key, True);
WorkStream.Position := 0;
LbEncodeBase64(WorkStream, OutStream);
end else begin
LbDecodeBase64(InStream, WorkStream);
WorkStream.Position := 0;
RSAEncryptStream(WorkStream, OutStream, Key, False);
end;
OutStream.Position := 0;
SetLength(Result, OutStream.Size);
OutStream.Read(Result[1], OutStream.Size);
InStream.Free;
OutStream.Free;
WorkStream.Free;
end;
{ == TLbRSAKey ============================================================= }
constructor TLbRSAKey.Create(aKeySize : TLbAsymKeySize);
{ initialization }
begin
inherited Create(aKeySize);
FModulus := TLbBigInt.Create(cLbAsymKeyBytes[FKeySize]);
FExponent := TLbBigInt.Create(cLbAsymKeyBytes[FKeySize]);
end;
{ -------------------------------------------------------------------------- }
destructor TLbRSAKey.Destroy;
{ finalization }
begin
FModulus.Free;
FExponent.Free;
inherited Destroy;
end;
{ -------------------------------------------------------------------------- }
procedure TLbRSAKey.Assign(aKey : TLbAsymmetricKey);
{ copy exponent and modulus values from another key }
begin
inherited Assign(aKey);
if (aKey is TLbRSAKey) then begin
FModulus.Copy(TLbRSAKey(aKey).Modulus);
FExponent.Copy(TLbRSAKey(aKey).Exponent);
end;
end;
{ -------------------------------------------------------------------------- }
procedure TLbRSAKey.Clear;
{ reset exponent and modulus }
begin
FModulus.Clear;
FExponent.Clear;
end;
{ -------------------------------------------------------------------------- }
function TLbRSAKey.GetModulusAsString : string;
{ return "big to little" hex string representation of modulus }
begin
Result := FModulus.IntStr;
end;
{ -------------------------------------------------------------------------- }
procedure TLbRSAKey.SetModulusAsString(Value : string);
{ set modulus to value represented by "big to little" hex string }
var
Buf : array[Byte] of Byte;
begin
FillChar(Buf, SizeOf(Buf), #0);
HexToBuffer(Value, Buf, cLbAsymKeyBytes[FKeySize]);
FModulus.CopyBuffer(Buf, cLbAsymKeyBytes[FKeySize]);
FModulus.Trim;
end;
{ -------------------------------------------------------------------------- }
function TLbRSAKey.GetExponentAsString : string;
{ return "big to little" hex string representation of exponent }
begin
Result := FExponent.IntStr;
end;
{ -------------------------------------------------------------------------- }
procedure TLbRSAKey.SetExponentAsString(Value : string);
{ set exponent to value represented by "big to little" hex string }
var
Buf : array[Byte] of Byte;
begin
FillChar(Buf, SizeOf(Buf), #0);
HexToBuffer(Value, Buf, cLbAsymKeyBytes[FKeySize]);
FExponent.CopyBuffer(Buf, cLbAsymKeyBytes[FKeySize]);
FExponent.Trim;
end;
{------------------------------------------------------------------------------}
function TLbRSAKey.CreateASNKey(Input : pByteArray; Length : Integer) : Integer;
const
TAG30 = $30;
var
ExpSize : Integer;
ModSize : Integer;
Total : Integer;
pInput : PByteArray;
Max : Integer;
begin
pInput := Input;
Max := Length;
ModSize := EncodeASN1(FModulus, pInput, Max);
ExpSize := EncodeASN1(FExponent, pInput, Max);
Total := ExpSize + ModSize;
CreateASN1(Input^, Total, TAG30);
Result := Total;
end;
{------------------------------------------------------------------------------}
function TLbRSAKey.ParseASNKey(Input : PByte; Length : Integer) : Boolean;
var
Tag : Integer;
Max : Integer;
pInput : PByte;
begin
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -