高级加密标准(英语:Advanced Encryption Standard,缩写:AES),在密码学中又称Rijndael加密法,该方法已有大量代码实现在网上。出于保护PLC 数据的目的,开发了Step7 的AES 算法模块AES(加密),DAES(解密)。该模块已完成初步调试和算法优化,在CPU1516 运行时间小于200us。商业用途可联系本人。
该算法模块有以下特点:
1.运行速度快,可满足实时任务需求
2.可用户制定密钥。
3.标准算法可与 .NET 和其它计算机的算法联合运用
4.可重新定义字符替换表。
5.充分运用TIA 的保密机制,该算法有较高安全性。(除非TIA 的保密机制被破解,破解者可看到密钥)
6已在CPU 1510SP-1 PN(6ES7 510-1DJ01-0AB0), CPU 1511-1 PN(6ES7 511-1AK01-0AB0)6ES7 516-3AN00-0AB0 等多个型号CPU 运行。
由于加密算法是公开的,加/解密共用一个密钥,泄露了密钥 key 就等于泄露的原始数据。为保证密钥Key 不泄露,不可将Key 放在接口或背景数据,以防泄露Key 。 Key 处理方法如下:
1.Key 赋值直接写到某个FC/FB 块,然后对整个FC/FB 加密
// "AES" 加密数据 16个
REGION AES
FOR #i := 0 TO 3 DO
FOR #j := 0 TO 3 DO
#Carry[#i, #j] := #SBuffer[#i * 4 + #j];
END_FOR;
END_FOR;
REGION 设定 #Key
#Key[0] := 16#01;
#Key[1] := 16#06;
#Key[2] := 16#30;
#Key[3] := 16#43;
#Key[4] := 16#56;
#Key[5] := 16#27;
#Key[6] := 16#45;
#Key[7] := 16#44;
#Key[8] := 16#51;
#Key[9] := 16#79;
#Key[10] := 16#AF;
#Key[11] := 16#04;
#Key[12] := 16#8A;
#Key[13] := 16#6F;
#Key[14] := 16#99;
#Key[15] := 16#21;
END_REGION
REGION
FOR #i := 0 TO 3 DO
#RoundKey[(#i * 4) + 0] := #Key[(#i * 4) + 0];
#RoundKey[(#i * 4) + 1] := #Key[(#i * 4) + 1];
#RoundKey[(#i * 4) + 2] := #Key[(#i * 4) + 2];
#RoundKey[(#i * 4) + 3] := #Key[(#i * 4) + 3];
END_FOR;
FOR #i := #AES_Nk TO 43 DO
#K := (#i - 1) * 4;
#tempa[0] := #RoundKey[#K + 0];
#tempa[1] := #RoundKey[#K + 1];
#tempa[2] := #RoundKey[#K + 2];
#tempa[3] := #RoundKey[#K + 3];
IF (#i MOD #AES_Nk) = 0 THEN
// This function shifts the 4 bytes in a word to the left once.
// [a0,a1,a2,a3] becomes [a1,a2,a3,a0]
// Function RotWord()
#tk := #tempa[0];
#tempa[0] := #tempa[1];
#tempa[1] := #tempa[2];
#tempa[2] := #tempa[3];
#tempa[3] := #tk;
#tempa[0] := #SBOX[#tempa[0]];
#tempa[1] := #SBOX[#tempa[1]];
#tempa[2] := #SBOX[#tempa[2]];
#tempa[3] := #SBOX[#tempa[3]];
#tempa[0] := #tempa[0] XOR #Rcon[#i / #AES_Nk];
END_IF;
#j := #i * 4;
#K := (#i - #AES_Nk) * 4;
#RoundKey[#j + 0] := #RoundKey[#K + 0] XOR #tempa[0];
#RoundKey[#j + 1] := #RoundKey[#K + 1] XOR #tempa[1];
#RoundKey[#j + 2] := #RoundKey[#K + 2] XOR #tempa[2];
#RoundKey[#j + 3] := #RoundKey[#K + 3] XOR #tempa[3];
END_FOR;
END_REGION
REGION
FOR #i := 0 TO 4 - 1 DO
FOR #j := 0 TO 3 DO
#Carry[#i, #j] := #Carry[#i, #j] XOR #RoundKey[#i * #Nb + #j];
END_FOR;
END_FOR;
END_REGION
REGION
FOR #round := 1 TO #Nr - 1 DO
REGION SubBytes(#state);
FOR #i := 0 TO 3 DO
FOR #j := 0 TO 3 DO
#Carry[#j, #i] := #SBOX[#Carry[#j, #i]];
END_FOR;
END_FOR;// Statement section REGION
END_REGION
REGION
#tk := #Carry[0, 1];
#Carry[0, 1] := #Carry[1, 1];
#Carry[1, 1] := #Carry[2, 1];
#Carry[2, 1] := #Carry[3, 1];
#Carry[3, 1] := #tk;
// Rotate second row 2 columns to left
#tk := #Carry[0, 2];
#Carry[0, 2] := #Carry[2, 2];
#Carry[2, 2] := #tk;
#tk := #Carry[1, 2];
#Carry[1, 2] := #Carry[3, 2];
#Carry[3, 2] := #tk;
// Rotate third row 3 columns to left
#tk := #Carry[0, 3];
#Carry[0, 3] := #Carry[3, 3];
#Carry[3, 3] := #Carry[2, 3];
#Carry[2, 3] := #Carry[1, 3];
#Carry[1, 3] := #tk;
END_REGION
REGION
FOR #i := 0 TO 3 DO
(* 。。。此处省略部分程序*)
END_FOR;
END_REGION
REGION
FOR #i := 0 TO 3 DO
FOR #j := 0 TO 3 DO
#Carry[#i, #j] := #Carry[#i, #j] XOR #RoundKey[(#round * #Nb * 4) + #i * #Nb + #j];
END_FOR;
END_FOR;
END_REGION
;
END_FOR;
END_REGION
REGION
FOR #i := 0 TO 3 DO
FOR #j := 0 TO 3 DO
#Carry[#i, #j] := #SBOX[#Carry[#i, #j]];
END_FOR;
END_FOR;
END_REGION
REGION
#tk := #Carry[0, 1];
#Carry[0, 1] := #Carry[1, 1];
#Carry[1, 1] := #Carry[2, 1];
#Carry[2, 1] := #Carry[3, 1];
#Carry[3, 1] := #tk;
#tk := #Carry[0, 2];
#Carry[0, 2] := #Carry[2, 2];
#Carry[2, 2] := #tk;
#tk := #Carry[1, 2];
#Carry[1, 2] := #Carry[3, 2];
#Carry[3, 2] := #tk;
#tk := #Carry[0, 3];
#Carry[0, 3] := #Carry[3, 3];
#Carry[3, 3] := #Carry[2, 3];
#Carry[2, 3] := #Carry[1, 3];
#Carry[1, 3] := #tk;
END_REGION
REGION
FOR #i := 0 TO 3 DO
FOR #j := 0 TO 3 DO
#Carry[#i, #j] := #Carry[#i, #j] XOR #RoundKey[(#Nr * #Nb * 4) + #i * #Nb + #j];
END_FOR;
END_FOR;
END_REGION
FOR #i := 0 TO 3 DO
FOR #j := 0 TO 3 DO
#SBuffer[#i * 4 + #j] := #Carry[#i, #j];
END_FOR;
END_FOR;
END_REGION
运用场景:(待续。。。。)
本人原创博客欢迎转载、引用,注明出处即可。