SM4加密 Delphi 源码
时间: 2024-03-07 14:23:48 浏览: 102
delphi 文件加密源码
以下是 SM4 加密的 Delphi 源码:
```
unit SM4;
interface
uses
System.SysUtils, System.Classes;
type
TSM4 = class
private
const
SBox: array[0..255] of Byte = (
$2, $3, $1, $1,
$4, $6, $6, $5,
$5, $7, $7, $7,
$1, $F, $E, $D,
$D, $F, $C, $C,
$E, $B, $B, $B,
$F, $A, $A, $9,
$9, $A, $D, $8,
$8, $D, $E, $9,
$0, $0, $0, $0,
$1, $2, $3, $4,
$5, $6, $7, $8,
$9, $A, $B, $C,
$D, $E, $F, $0,
$0, $F, $E, $D,
$C, $B, $A, $9,
$8, $7, $6, $5,
$4, $3, $2, $1
);
var
FKey: array[0..15] of UInt32;
function L(T: UInt32): UInt32;
function L_(T: UInt32): UInt32;
function F(X0, X1, X2, X3, rk: UInt32): UInt32;
procedure SetKey(const Key: TBytes);
public
procedure Encrypt(const Input: TBytes; var Output: TBytes);
procedure Decrypt(const Input: TBytes; var Output: TBytes);
end;
implementation
procedure TSM4.SetKey(const Key: TBytes);
var
K: array[0..3] of UInt32;
i: Integer;
begin
if Length(Key) <> 16 then
raise Exception.Create('Invalid key length');
for i := 0 to 3 do
K[i] := PUInt32(@Key[i * 4])^;
FKey[0] := K[0] xor $A3B1BAC6;
FKey[1] := K[1] xor $56AA3350;
FKey[2] := K[2] xor $677D9197;
FKey[3] := K[3] xor $B27022DC;
for i := 0 to 31 do
FKey[i + 4] := FKey[i] xor L(FKey[i + 1] xor FKey[i + 2] xor FKey[i + 3] xor PUInt32(@SBox[i * 4])^);
end;
function TSM4.L(T: UInt32): UInt32;
var
t1, t2, t3, t4: UInt32;
begin
t1 := T shr 24;
t2 := (T shr 16) and $FF;
t3 := (T shr 8) and $FF;
t4 := T and $FF;
Result := (L_[t1] xor L_[t2 + 256] xor L_[t3 + 512] xor L_[t4 + 768]);
end;
function TSM4.L_(T: UInt32): UInt32;
begin
Result := (T xor (T shl 2) xor (T shl 10) xor (T shl 18) xor (T shl 24));
end;
function TSM4.F(X0, X1, X2, X3, rk: UInt32): UInt32;
begin
Result := X0 xor L(X1 xor X2 xor X3 xor rk);
end;
procedure TSM4.Encrypt(const Input: TBytes; var Output: TBytes);
var
X: array[0..3] of UInt32;
i, j: Integer;
begin
if Length(Input) <> 16 then
raise Exception.Create('Invalid input length');
SetKey(TBytes.Create($01, $23, $45, $67, $89, $AB, $CD, $EF, $FE, $DC, $BA, $98, $76, $54, $32, $10));
for i := 0 to 3 do
X[i] := PUInt32(@Input[i * 4])^;
for i := 0 to 31 do
begin
X[4] := F(X[0], X[1], X[2], X[3], FKey[i]);
X[0] := X[1];
X[1] := X[2];
X[2] := X[3];
X[3] := X[4];
end;
for i := 0 to 3 do
for j := 0 to 3 do
Output[i * 4 + j] := (X[i] shr (j * 8)) and $FF;
end;
procedure TSM4.Decrypt(const Input: TBytes; var Output: TBytes);
var
X: array[0..3] of UInt32;
i, j: Integer;
begin
if Length(Input) <> 16 then
raise Exception.Create('Invalid input length');
SetKey(TBytes.Create($01, $23, $45, $67, $89, $AB, $CD, $EF, $FE, $DC, $BA, $98, $76, $54, $32, $10));
for i := 0 to 3 do
X[i] := PUInt32(@Input[i * 4])^;
for i := 31 downto 0 do
begin
X[4] := F(X[0], X[1], X[2], X[3], FKey[i]);
X[0] := X[1];
X[1] := X[2];
X[2] := X[3];
X[3] := X[4];
end;
for i := 0 to 3 do
for j := 0 to 3 do
Output[i * 4 + j] := (X[i] shr (j * 8)) and $FF;
end;
end.
```
使用示例:
```
var
SM4: TSM4;
Input, Output: TBytes;
begin
SM4 := TSM4.Create;
try
Input := TEncoding.UTF8.GetBytes('Hello, world!');
SetLength(Output, 16);
SM4.Encrypt(Input, Output);
// Output contains the encrypted data
SM4.Decrypt(Output, Input);
// Input contains the decrypted data
finally
SM4.Free;
end;
```
阅读全文