📄 aesunit.pas
字号:
unit aesunit;
interface
function AES(status:string;key:string; time:integer):String;
function INAES(status:string;key:string;time:integer):String;
function KeyDistribution (KeyLicence:String; AllotLicence:String; MeterID:String; KeyWord:String) : String;
function DynamicKey (MeterID:String; Key:String; Number:integer) : String;
var
PKeyLicence, PAllotLicence : String;
implementation
uses
SysUtils;
const
Box:array[0..9] of integer=(6,8,4,9,7,2,1,0,5,3);
InBox:array[0..9] of integer=(7,6,5,9,2,8,0,4,1,3);
//加密部分
//S盒置换
function S_Box(status:string):String;
var
i,len:integer;
s1:string;
begin
s1:='';
len:=length(status);
for i:=1 to len do
s1:=s1+IntToStr(Box[StrToInt(status[i])]);
S_Box:=S1;
end;
//行移位
function ShiftRow(status:String;time:integer):String;
var
i,j,k,len,n1:integer;
Matrix:array[0..3,0..7] of char;
Temp:array[0..7] of char;
st:string;
begin
len:=length(status);
if len=6 then n1:=3 else n1:=4;
for i:=0 to len-1 do
begin
j:=i mod n1;
k:=i div n1;
Matrix[j,k]:=status[i+1];
end;
for i:=1 to n1-1 do
begin
for j:=0 to (len div n1)-1 do
begin
k:=((j+i) mod (len div n1));
temp[j]:=Matrix[i,k];
end;
for j:=0 to (len div n1)-1 do Matrix[i,j]:=temp[j];
end;
//*对明文长度为12十进制数时行交换处理*/
if len=12 then
for j:=0 to (len div n1)-1 do
begin
k:=(Time-1) mod (n1-1) ;
Temp[j]:=Matrix[k,j];
Matrix[k,j]:=Matrix[n1-1,j];
Matrix[n1-1,j]:=Temp[j];
end;
//*对明文长度为6、8十进制数时第2列循环处理*/
if (len=6) or (len=8) then
begin
for i:=0 to n1-1 do
begin
k:=(i+1) mod n1;
Temp[i]:=Matrix[k,1];
end;
for i:=0 to n1-1 do
Matrix[i,1] := Temp[i];
end;
//*最后将移位后数据复制回去原数组*/
st:='';
for i:=0 to len-1 do
begin
j:=i mod n1;
k:=i div n1;
st:=st + Matrix[j,k];
end;
ShiftRow:=st;
end;
//列混合
function MixClumn(status:string):string;
var
i,j,k,len,n1,n2:integer;
Matrix:array[0..3,0..7] of integer;
st:string;
begin
len:=length(status);
if len=6 then n1:=3 else n1:=4;
n2:=len div n1;
for i:=0 to n1*n2-1 do
begin
k:=i div n1 ;
j:=i mod n1;
Matrix[j,k]:=StrToInt(status[i+1]);
end;
//*明文为8(Hash函数)、12、16位十进制数的4维列混合处理*/
st:='';
if n1=4 then
for i:=0 to n2-1 do
begin
St:=st+IntToStr((5* Matrix [0,i] + 3* Matrix [1,i] + 2* Matrix [2,i] + Matrix [3,i]) mod 10);
St:=st+IntToStr(( Matrix [0,i] + 5* Matrix [1,i] + 3* Matrix [2,i] + 2* Matrix [3,i]) mod 10);
St:=st+IntToStr((2* Matrix [0,i] + Matrix [1,i] + 5* Matrix [2,i] + 3* Matrix [3,i]) mod 10);
St:=st+IntToStr((3* Matrix [0,i] + 2* Matrix [1,i] + Matrix [2,i] + 5* Matrix [3,i]) mod 10);
end;
//*明文为6位十进制数(Hash函数)的3维列混合处理*/
if n1=3 then
for i:=0 to n2-1 do
begin
St:=st+IntToStr((5* Matrix [0,i] + 4* Matrix [1,i] + 2* Matrix [2,i]) mod 10);
St:=st+IntToStr((2* Matrix [0,i] + 5* Matrix [1,i] + 4* Matrix [2,i]) mod 10);
St:=st+IntToStr((4* Matrix [0,i] + 2* Matrix [1,i] + 5* Matrix [2,i]) mod 10);
end;
MixClumn:=st;
end;
//密钥扩展
function EK(key:string; time ,len:integer):String;
var
i1,i,j,k,rcc,n,n1,lenk:integer;
st:string;
Temp:array[0..3] of string;
begin
lenk:=length(key);
st:=copy(key,1,lenk);
if len=6 then n1:=3 else n1:=4;
if lenk=32 then
begin
Rcc:=(Time*len) div 32;
if ((Rcc * 32) < (time*len)) then Rcc:=Rcc+1;
for i1:=0 to Rcc do //i1为扩展的轮次
begin
for i:=0 to 7 do //i为列
begin
if (32+i*4+i1*32)>=(time+1)*len then break;
if (i =0) then //每32位开始时密钥的列要移位
begin
//*行移位*/
for j:=0 to 2 do temp[j]:=st[i*4 + 30 + j+i1*32];
temp[3]:=St[i*4+28 +i1*32];
st:=st+IntToStr( (StrToInt( St[i*4+1+i1*32] ) + Box[ StrToInt(temp[0]) ] + i1+1) mod 10 ); //每32位开始列的第一位扩展
for j:=1 to 3 do //该列后面的3位扩展
St:=St+IntToStr((StrToInt(St[i*4 + j+1+i1*32]) + Box[StrToInt(temp[j])] ) mod 10);
end
else
begin
k:=32 + i*4+ i1*32;
if (k>=(time+1)*len) then break; //如果扩展的密钥长度=time*len则停止扩展退出
for j:=0 to 3 do //其它列的扩展
st:=st+IntToStr((StrToInt(St[i*4 + j+1+i1*32]) + StrToInt(St[4*i+28 + j +1+i1*32]) ) mod 10);
end;
end;
end;
end;
//*对于密钥长为6、8位的轮密钥扩展*/
if (((len=6) or (len=8) or (lenk mod 4=0)) and (lenk<>32)) then
begin
n:=lenk div n1;
for k:=0 to time-1 do
begin
for i:=0 to n1-2 do temp[i]:=st[i+n1*(n-1)+2+k*n*n1];
temp[n1-1]:=st[n1*(n-1)+1+k*n*n1];
st:=st+IntToStr((StrToInt(st[1+k*n*n1]) + Box[StrToInt(temp[0])] + 1+k) mod 10);
for i:=1 to n1-1 do st:=st+IntToStr((StrToInt(St[i+1+k*n*n1]) + Box[StrToInt(temp[i])] ) mod 10);
for j:=0 to n-2 do
if length(st)<(time+1)*len then
for i:=0 to n1-1 do St:=St+IntToStr((StrToInt(St[i+n1+1+k*n*n1]) + StrToInt(St[i+n1+1+(n+j-1)*n1+k*n*n1])) mod 10);
end;
end;
EK:=St;
end;
//轮密钥控制变换
function AddRoundKey (Status:String; bKey:String; time:integer) : String;
var
TempString : String;
addressBegin,enter : integer;
i, j,len, temp : integer;
begin
len:=length(status);
addressBegin := len * time;
enter := 0;
for i := addressBegin to addressBegin+len-1 do enter := enter + StrToInt(bKey[i+1]);
enter := enter mod 4;
TempString := '';
for i := 0 to len-1 do
begin
j := (i + enter) mod 4;
if j = 0 then TempString := TempString + InttoStr( (StrToInt( Status[i+1] ) + StrToInt( bKey[i+addressBegin+1] ) ) mod 10);
if j = 1 then
Begin
temp := (StrToInt( Status[i+1] ) - StrToInt(bKey[i+addressBegin+1])) mod 10;
if temp < 0 then temp := 10 + temp;
TempString := TempString + InttoStr( temp );
End;
if j = 2 then TempString := TempString + InttoStr( (StrToInt( Status[i+1] ) + Box[ StrToInt(bKey[i+addressBegin+1]) ]) mod 10);
if j = 3 then
Begin
temp := (StrToInt( Status[i+1] ) - Box[ StrToInt(bKey[i+addressBegin+1]) ]) mod 10;
if temp < 0 then temp := 10 + temp;
TempString := TempString + InttoStr( temp );
End;
end;
AddRoundkey := TempString;
end;
//AES加密函数
function AES(status:string;key:string; time:integer):String;
var
ij,n1,n2,len:integer;
begin
//*确定明文的行列数*/
len:=length(status);
// lenk:=length(key);
if (len=6) then n1:=3 else n1:=4;
n2:=len div n1;
if len<>n1*n2 then exit;
//*对明文长度为12、16、20位十进制数的加密*/
if (((len=12) or (len=16) or (len=20)) and (time>0)) then
begin
status:=AddRoundKey(status,key,0); //初始轮密钥加
key:=EK(key, time, len); //密钥扩展,一次性扩展
for ij:=1 to time-1 do
begin
status:=S_box(status);
status:=ShiftRow(status,ij);
status:=MixClumn(status);
status:=AddRoundKey(status,key,ij);
end;
status:=S_box(status); //最后一轮加密
status:=ShiftRow(status,time);
status:=AddRoundKey(status,key,time);
end;
//*对明文中的Hash函数的加密和对32位长度的十进制数2轮AES加密*/
if ((len=6) or (len=8) or (len=32)) then
begin
key:=EK(key,2,len);
status:=AddRoundKey(status,key,0);
status:=S_box(status);
status:=ShiftRow(status,1);
status:=MixClumn(status);
status:=AddRoundKey(status,key,1);
status:=S_box(status);
status:=ShiftRow(status,2);
status:=AddRoundKey(status,key,2);
end;
AES:=status;
end;
//解密程序
//S盒置换的逆InS_Box(status,len)
function InS_Box(status:string):String;
var
i,len:integer;
s1:string;
begin
len:=length(status);
s1:='';
for i:=1 to len do
s1:=s1+IntToStr(InBox[StrToInt(status[i])]);
InS_Box:=S1;
end;
//行移位的逆InShiftRow(status,len,time,n1)
function InShiftRow(status:String;time:integer):String;
var
i,j,k,len,n1:integer;
Matrix:array[0..3,0..7] of char;
Temp:array[0..7] of char;
st:string;
begin
len:=length(status);
if len=6 then n1:=3 else n1:=4;
for i:=0 to len-1 do
begin
j:=i mod n1;
k:=i div n1;
Matrix[j,k]:=status[i+1];
end;
//*对明文长度为12十进制数时行交换处理*/
if len=12 then
for j:=0 to (len div n1)-1 do
begin
k:=(Time-1) mod (n1-1) ;
Temp[j]:=Matrix[k,j];
Matrix[k,j]:=Matrix[n1-1,j];
Matrix[n1-1,j]:=Temp[j];
end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -