推荐设备MORE

北京企业网站建设教程—后来

北京企业网站建设教程—后来

疑难问题

用 C# 撰写 AES 类结构涵数

日期:2021-02-12
我要分享
用 C# 撰写 AES 类结构涵数

来源于: 百优資源网 创作者:管理方法员

关键提醒:如今我已科学研究了组成 AES 数据加密优化算法的每个成份,我将用 C# 来完成它。官方网的 AES 优化算法标准包括在联邦政府信息内容解决规范出版发行物197 (Federal Information Processing Standards Publication 197)中。我打算尽量切合地以它做为我的完成的基本,

用 C# 撰写 AES 类结构涵数

五、用 C# 撰写 AES 类结构涵数
如今我已科学研究了组成 AES 数据加密优化算法的每个成份,我将用 C# 来完成它。官方网的 AES 优化算法标准包括在联邦政府信息内容解决规范出版发行物197 (Federal Information Processing Standards Publication 197)中。我打算尽量切合地以它做为我的完成的基本,可是我迅速发觉这一标准也是一个基础理论参考文献并非一个完成的指导。以便将这一官方网标准做为資源来应用,我应用 的自变量名与规范出版发行物中常用的同样。(就算他们是那麼晦涩难懂,如“Nr”和“W”)。
  我的设计方案应用9数量据组员和一个枚举类型种类,以下所显示:
public enum KeySize { Bits128, Bits192, Bits256 }; private int Nb; private int Nk; private int Nr; private byte[] key; private byte[,] Sbox; private byte[,] iSbox; private byte[,] w; private byte[,] Rcon; private byte[,] State;
  由于密匙长短只有是12八位、192位或256位比特,它是是非非常适于用枚举类型种类:
public enum KeySize { Bits128, Bits192, Bits256 };
  该标准文本文档一般用字节数做为基本存储模块而并不是用4字节数的字做为2个关键数据信息组员的长短。这2个组员 Nb 和 Nk 意味着 以字为企业的块长及其以字为企业的密匙长短。Nr意味着轮数。块长短一直16字节数(或这说成 128 位,即是 AES 的 4个字),因而它能够被申明为一个变量定义。密匙长短 按照枚举类型主要参数 KeySize 的值被取值为 4、6 或 8。AES 优化算法注重根据很多轮数来提升数据加密数据信息的繁杂性。轮数是10、12或14中的随意一个而且是根据登陆密码剖析学基础理论的。它立即在于密匙长短。
当设计方案一个类插口时,我很喜欢向之后做。我构想从运用程序中启用结构涵数和方式。应用这一方法,我打算象下边那样来案例化一个 AES 目标:
Aes a = new Aes(the key size, the seed key)
我启用的数据加密调解密例程以下:
a.Cipher(plainText, cipherText); a.InvCipher(cipherText, decipheredText);
我挑选少量愚钝的方式来取名 Cipher 和 InvCipher,由于他们是用在 AES 标准文本文档中的。这儿是 AES 类结构涵数的编码为:
public Aes(KeySize keySize, byte[] keyBytes) { SetNbNkNr(keySize); this.key = new byte[this.Nk * 4]; keyBytes.CopyTo(this.key, 0); BuildSbox(); BuildInvSbox(); BuildRcon(); KeyExpansion(); }
该结构涵数最先启用一个輔助方式 SetNbNkNr 给 Nb、Nk 和 Nr 取值,如 Figure 8 所显示。假如考虑到到高效率,你可以能将这种编码立即放进结构涵数 以免方式启用的花销。
接下去,你务必将传到结构涵数的字节数复制到类域自变量中。密匙用其他的类域申明,而且用以下方式得到它的值:
this.key = new byte[this.Nk * 4]; keyBytes.CopyTo(this.key, 0);
  我打算在结构涵数中启用独享輔助方式 BuildSbox 和 BuildInvSbox 来原始化更换表 Sbox[] 和 iSbox[] 。如今密匙拓展例程 、Cipher 方式和 InvCipher 方式各有都必须 Sbox[] 和 iSbox[],因而我曾来能够在 Cipher 和 InvCipher 2个方式中原始化 Sbox[] 并启用 KeyExpansion 方式,可是将他们放进结构涵数会编码构造更为清楚。在 Figure 9 中 sBox[] 被添充。添充 iSbox[] 编码 相近。以便易读性对编码开展了断构化解决。如同后边你将见到的,也有此外一个能够挑选的让人诧异的方式为 Sbox 和 iSbox 表出示值。
在结构涵数中申明密匙生产调度表 w[]、轮参量表 Rcon[] 和情况引流矩阵 State[],并且用独享輔助方式来给 Rcon[] 和 w[] 取值我认为好像是机构他们的最好方法,但那关键還是个设计风格难题。换置轮参量表 Rcon 的取值编码参照Figure 7。
回忆一下,GF(28)中,Rcon[] 每一行左侧的字节数都 2 的幂,因而这一表能用下边的方式创建:
newVal = prevVal * 0x02;
AES 结构涵数新建立完密匙生产调度表 w[] 后完毕,而 w[] 是在 KeyExpansion 方式中进行的(参照 Figure 10)。 其编码非常简易。标准文本文档应用一个假定的 4-字节数的篇幅据种类。由于 C# 沒有那般的种类,但能够用一个4个字节数的数字能量数组来仿真模拟。再用 new 实际操作符为密匙生产调度 表 w[] 分派室内空间后,w[] 最开始的 Nk(4, 6, 或 8) 行从被传送到结构涵数的種子密匙 key[] 数字能量数组中获值。
this.w[row,0] = this.key[4*row]; this.w[row,1] = this.key[4*row+1]; this.w[row,2] = this.key[4*row+2]; this.w[row,3] = this.key[4*row+3];
2个字节数互相的异或实际操作在这里个编码中不断产生。它必须一些从 byte 到 int 的强制性种类变换并转返回 byte,由于异或实际操作“^”不是能界定在 C# 的 byte 种类上,比如:
temp[0] = (byte)( (int)temp[0] ^ (int)this.Rcon[row/Nk,0] );
用于取代:
temp[0] = temp[0] ^ this.Rcon[row/Nk,0];
KeyExpansion 方式有标准地启用独享方式 SubWord 和 RotWord 以维持同标准取名的一致性。另外,由于在C#中沒有 word种类,我用 4字节数数字能量数组完成了一个字。SubWord 和 RotWord 的编码是非常简易,参照文中附加的 AesLib 源码,它应当非常容易了解。
略微具有一些方法的一部分是在 SubWord 中搜索取代值。回忆一下,以便找寻替代值,你将键入字节数分为最左侧的4位比特和最右侧的4位比特。针对一个给定字节数,用 实际操作符右移 4 位将获得 x 数据库索引,而且与 0000 1111 开展逻辑性与获得 y 值。尽管一些长,但比具体编码更可读,我能象下边那样:
int x = word[0] 4; int y = word[0] 0x0f; byte substitute = this.Sbox[x,y]; result[0] = substitute;
替代我原先用的编码:
result[0] = this.Sbox[ word[0] 4, word[0] 0x0f ];
总体来说,AES 结构涵数接纳一个密匙的长短为128,192 或 256 位和一个字节数数字能量数组種子密匙值。结构涵数为键入块长短,種子密匙长短 及其数据加密优化算法的轮数取值,并将種子密匙复制到一个名叫 key 的数据信息组员中。结构涵数还建立了四个表:2个由数据加密调解密方式应用的更换表,一个轮参量表,和一个轮密匙的密匙生产调度表。


 

六、用C#撰写的 AES Cipher 方式

Cipher方式如 Figure 11 所显示。它确实十分简易,由于它分出了大部分分的工作中给独享方式AddRoundKey, SubBytes, ShiftRows 和 MixColumns。
Cipher 方式以复制密文键入数字能量数组到情况引流矩阵 State[] 为刚开始。最开始启用 AddRoundKey 以后,Cipher 方式比总轮数少迭代更新一次。在最终一轮时,如同标准中常说的那般,MixColumns 启用被省去了。
AddRoundKey 和 SubBytes 独享方式的编码如 Figure 12 所显示。AddRoundKey 方式必须了解它处于那一轮,便于它恰当引入4行密匙生产调度数字能量数组 w[]。一定要注意 State[r,c] 是用 w[c,r] 来异或其实不是w[r,c]。SubBytes 方式从键入字节数中获取数据库索引,与 KeyExpansion 方式中常用的右移4位和 0x0f 屏蔽掉技术性同样。
ShiftRows 方式的编码如 Figure 13 所显示。回忆一下,ShiftRows(将会称为 RotateRows 更强)将 row[0] 向左转动 0 个部位,将 row[1] 向左转动 1 部位这些。
把 State[] 复制到 temp[] 引流矩阵以后,随后用下边的这方面编码完成变换:
this.State[r, (c + r) % Nb ] = temp[r,c];
这儿运用%实际操作符的优势抱合一行。
MixColumns 方式(Figure 14)用GF(28)加和乘,以字节数列中常有其他值的线形组成对每个字节数开展更换。
乘法常用的变量定义系数根据域论的,而且是0x01, 0x02或 0x03中的随意一个值。给定某一列 c ,其取代式以下:
State[0,c] = 0x02 * State[0,c] + 0x03 * State[1,c] + 0x01 * State[2,c] + 0x01 * State[3,c] State[1,c] = 0x01 * State[0,c] + 0x02 * State[1,c] + 0x03 * State[2,c] + 0x01 * State[3,c] State[2,c] = 0x01 * State[0,c] + 0x01 * State[1,c] + 0x02 * State[2,c] + 0x03 * State[3,c] State[3,c] = 0x03 * State[0,c] + 0x01 * State[1,c] + 0x01 * State[2,c] + 0x02 * State[3,c]
这种表述式略微一些长,因而我打算撰写回到 GF(28)与 0x01,0x02 和 0x03 之乘积的独享輔助涵数。这种輔助涵数十分短。比如,一个字节数 b 被 0x03 域乘的编码以下:
return (byte) ( (int)gfmultby02(b) ^ (int)b );
如同我前边探讨的,被 0x02 乘是全部 GF(28) 乘法的操作过程。我启用了我的 gfmultby02 方式,我更改了应用与标准同样的方式取名国际惯例,标准上称此例程为 xtime。
Cipher 方式其键入不断运用四个实际操作来造成数据加密的輸出。AddRoundKey 用来源于单独初始種子密匙的多种轮密匙来取代字节数。SubBytes 用某一更换表格中的值取代字节数。ShiftRows 用移动字节数行换置字节数,而 MixColumns 用某一列的域加和乘法值来取代字节数。

 

七、用C#撰写 AES InvCipher 方式

AES 解密优化算法身后的基本准则非常简单:解密一个数据加密块,也便是以反方向次序复原(Undo)每一个实际操作。虽然它是基本要素,但仍几个关键点要解决。
AES标准称解密例程为 InvCipher,而并不是 Decipher 或 Decrypt 中的一个。它是 AES 身后的数学课基本的体现,它根据可逆的数学课实际操作。
假如你将这一编码和 Cipher 编码较为得话,你能见到它比你预估的好看许多,可是有二点列外。最先,在 InvCipher 方式中逆方式启用(如 InvSubBytes)次序其实不彻底与在 Cipher 方式中相对启用(如 SubBytes)的反向次序恰好同样。次之,InvCipher 启用的是一个 AddRoundKey 方式而并不是 InvAddRoundKey 方式。非常值得留意的是 InvCipher 优化算法用密匙生产调度表其实不是以较高序号的数据库索引处刚开始往下解决至第0行。
InvSubBytes,InvShiftRows 和 InvMixColumns 方式的编码和与之相关的 SubBytes,ShiftRows和 MixColumns 方式的编码十分贴近。InvSubBytes 方式基本上便是 SubBytes 方式,仅仅它用逆更换表 iSbox[] 而并不是 Sbox[] 表。
如同你可以能猜想到的,iSbox[] 便是复原一切被 Sbox[] 解决的相匹配实际操作。例如,假如给你字节数 b 相当于 0x20,并在 Sbox[] 中寻找其替代值,你获得 0xb7。假如你一直在 iSbox[] 中寻找 0xb7的取代值,你即可获得 0x20。
类似地,InvShiftRows 方式复原 ShiftRows 方式—— row[0] 被右移了 0 个部位,row[1] 被右移了 一个部位,row[2] 被右移了 2 个部位,而 row[3] 被右移了 3个部位。
InvMixColumns 方式复原 MixColumns 的工作中,但沒有用不言而喻的方式。回忆一下,MixColumns 用初始字节数列中的字节数线形组成更换情况引流矩阵中的每一个字节数,而且系数是 0x01,0x02,和 0x03,域论再一次获得运用。它证实逆计算是类似的,仅仅被 0x09,0x0b,0x0d 和 0x0e 乘,以下所显示:
State[0,c] = 0x0e * State[0,c] + 0x0b * State[1,c] + 0x0d * State[2,c] + 0x09 * State[3,c] State[1,c] = 0x09 * State[0,c] + 0x0e * State[1,c] + 0x0b * State[2,c] + 0x0d * State[3,c] State[2,c] = 0x0d * State[0,c] + 0x09 * State[1,c] + 0x0e * State[2,c] + 0x0b * State[3,c] State[3,c] = 0x0b * State[0,c] + 0x0d * State[1,c] + 0x09 * State[2,c] + 0x0e * State[3,c]
针对 MixColumns 方式,我打算专业写一个輔助涵数,而并不是内联进行早已较长的表述式或写一个一般的乘法輔助涵数。要我向你展现一下我示怎样撰写这一一切字节数 b 被参量 0x0e (在10进制中的14)乘的涵数,像一切数据一样,数据 14 能够被表明成 2 的幂的和,因而,14 相当于 2 + 4 + 8。而且 4 相当于 2 的平方,8 相当于 2 的立方,你可以以将14表明为 2 + 22 + 23。记牢加减法便是 GF(28)中上的异或(^),即然我早已拥有 gfmultby02 涵数,我能用它获得我的結果:
return (byte)( (int)gfmultby02(gfmultby02(gfmultby02(b))) ^ /* 23 + */ (int)gfmultby02(gfmultby02(b)) ^ /* 22 + */ (int)gfmultby02(b) ); /* 2 */
用以 AES 数据加密优化算法的全部的实际操作全是可逆的,因而解密优化算法实质上是数据加密的全部实际操作的倒转。

 

八、应用 AES 类

用C#完成 AES 的特点之一就简易。看一下 Figure 15,它就是我用于转化成輸出 Figure 1 的编码。申明了 16 字节数 密文键入硬编码值和 24 字节数(192位)的種子密匙后,一个 AES 目标被原始化,数据加密 Cipher 方式 将密文数据加密变成保密,随后再用 InvCipher 将保密解密。十分清晰和简易。
由于 AES 目标对于字节数数字能量数组开展解决,你可以以轻轻松松地用它解决.NET的其他数据信息种类。我建立了一个根据 Windows 的小Demo程序,它接纳一个 单纯性的标识符串——有 8 字符 (16-byte) ,对它开展数据加密调解密解决。运作界面如 Figure 16。
 

手机软件设计方案


Figure 16 数据加密 Demo 程序

  由于数据加密调解密例程都必须了解客户界定的密匙长短,我将它作为一个类范畴的自变量来申明,像那样:
private Aes.KeySize keysize;
留意種子密匙其实不是由客户界定的。这一demo 程序用一个“空密匙”(null key)做为種子密匙,根据为结构涵数出示一个哑主要参数new byte[16] 促使它所有由零字节数构成。哑主要参数的长短不是有关的,由于種子密匙還是要被原始化作零。空密匙数据加密调解密是一个非常容易和合理的方法来阻拦外部多数据不经意的查验。在System.Text 中的Encoding.Unicode.GetBytes和Encoding.Unicode.GetString 方式促使将一个.NET 标识符串变换成一个字节数数字能量数组越来越十分非常容易,相反亦然。
 

九、完成挑选
  如今要我们看一下文中AES 完成抽出现的一些关键的自变量,文中出示的编码将会出現的拓展,及其对于AES 的登陆密码剖析学进攻。
  与我以前解决的一切编码一样,AES 优化算法还可以用其他可选择的方式来完成。为何这太重要呢?AES 被尝试普遍运用于各种各样系统软件,从仅有非常少运行内存容积的智能化卡(smart cards)到大中型的好几处理器服务器系统软件。在很多状况下,特性是重要要素,而且有时候运行内存或解决器資源是比较有限的。客观事实上,AES 的每一个例程都能对于十分价格昂贵的运行内存資源开展特性提升,相反亦然。例如,为更换表Sbox[] 分派256 个值看上去仿佛非常简单直接。可是,这种值是根据GF(28) 基础理论的,他们都可以以用程序编写方法来转化成。反向更换表和轮参量表也是这般。
  可选择完成此外一个趣味的将会性是Cipher 和InvCipher 方式常用的GF(28) 乘法。我的完成编码是一个被0x02 乘的基本涵数,然后是六个启用gfmultby02 的额外涵数。另外一个将会性应当是写一个一一样的乘法涵数,并且用它替代我现阶段完成的七个独立涵数。另外一个极端化就是你能够用被0x01, 0x02, 0x03, 0x09, 0x0b, 0x0d 和0x0e 乘好的全部256 个将会的字节数值组成的一个详细乘积表。另外,完成GF(28) 乘法另外一方式是根据在2个256 个字节数的数字能量数组里搜索,一般称之为alog[] 和log[],由于他们在GF(28)中根据一些相近多数的方式。
  尽管这儿得出的AES 类彻底可用于数据加密一切方式的.NET数据信息,你可以能考虑到想要各种各样方式拓展它。最先,由于文中的关键取决于清晰地表述AES,全部 不正确查验被脱离掉,以我的工作经验,为某一象AES 那样的类加上有效总数的不正确查验可能造成三倍的编码量澎涨。由于AES 应用了那么多的数字能量数组,必须做许多数据库索引 界限查验。比如,所得出的结构涵数乃至也不查验種子密匙主要参数的长短。
你可以能还考虑到根据加上大量的特点来拓展AES 类。最显著的一个地区是加上数据加密调解密.NET基本数据信息种类的方式,例如:System.String 和System.Int32。更为开疆辟土的拓展将会会是完成一个 流数据信息数据加密类。
  AES 的安全性性如何呢?它是一个难以回应的难题,可是一般大部分人的建议是:它是现阶段可得到的最安全性的数据加密优化算法。AES 已被列入比一切现如今其他数据加密优化算法更 安全性的一种优化算法。在基础理论和实践活动基本上,AES 被觉得是“安全性的”,由于要破译它得话,唯一合理的方式是强制(brute-force)转化成全部将会的密匙。 假如密匙长短为256 位,还没有有己知的进攻能够在一个可接纳的時间内破译AES(就算在现如今更快的系统软件上,它还要花销多年時间)。
  留意对于AES 登陆密码最将会取得成功的进攻来源于一个容许時间挑选进攻的弱完成。进攻者用不一样的密匙并精准地精确测量出数据加密例程需要的時间。假如数据加密例程被粗心大意编号 ,因而实行時间便依靠于密匙值,它就会有将会推导出来相关密匙的信息内容。在AES 中,这类事儿最将会产生在MixColumns 例程中,由于有域乘。 对于这类进攻的2个安全性对策是添加虚命令,便于因此全部乘法都必须同样总数的命令,或是将域乘完成为一个查寻表,就象我前边叙述的那般。
  AES 有很多种将会的完成,特别是在是是应用查寻表而并不是测算。文中出示的AES 基本类能够被用以加解密一切方式的.NET数据信息或 被拓展成一个具备大量作用的类。


 
十、完毕语
  新的AES 将毫无疑问变成数据加密全部方式电子器件信息内容的客观事实上的规范,替代DES。AES 数据加密的数据信息在某类实际意义上是坚不可摧的,由于沒有己知的登陆密码剖析进攻能够解密AES 保密,除非是强制解析xml检索全部将会的256 位密匙。
  发了如今Microsoft .NET Framework 上完成AES 类的关键的阻碍是官方网文本文档是以一数量学家的见解,而并不是以一个手机软件开发设计者的见解来写的。特别是在是该标准假设阅读者十分了解GF(28) 域,并省去了好多个恰当完成AES 所必不可少的有关GF(28) 乘法的重要客观事实。我还在文中小试图勤奋除掉AES 的神密面纱,非常是紧紧围绕在GF(28) 域乘法一部分的。
以.NET Framework 库的方式从Microsoft 及其第三方供货商处得到对AES 的普遍适用仅仅一个時间难题。但是,处在诸多原因,让文中编码做为你的专业技能贮备依然是有使用价值的。这一完成特别是在简易,而且是低資源花销。此外,阅读文章并了解源码将使你可以订制AES 类且更合理地应用它的一切完成。
在一切手机软件设计方案全过程中安全性已已不是顾虑。AES 是一个重特大发展,应用并了解它将大大的提升手机软件系统软件的靠谱性和安全性性。

 

十一、用delphi撰写 AES方式
 

手机软件设计方案


检测demo:
数据加密:
procedure TForm1.Button1Click(Sender: TObject);
begin
  Case Combobox1.ItemIndex of
  0://12八位密匙数据加密
  CText.Text:=EncryptString(MText.Text,KText.Text,kb128,trim(ComboBox2.Text),trim(edit1.text));
  1://192位密匙数据加密
  CText.Text:=EncryptString(MText.Text,KText.Text,kb192,trim(ComboBox2.Text),trim(edit1.text));
  2://256位密匙数据加密
  CText.Text:=EncryptString(MText.Text,KText.Text,kb256,trim(ComboBox2.Text),trim(edit1.text));
  end;
  memo1.Lines.Add(getbase64);
end;
解密:
procedure TForm1.Button2Click(Sender: TObject);
begin
  Case Combobox1.ItemIndex of
  0://12八位密匙解密
  PText.Text:=DecryptString(CText.Text,KText.Text,kb128,trim(ComboBox2.Text),trim(edit1.text));
  1://192位密匙解密
  PText.Text:=DecryptString(CText.Text,KText.Text,kb192,trim(ComboBox2.Text),trim(edit1.text));
  2://256位密匙解密
  PText.Text:=DecryptString(CText.Text,KText.Text,kb256,trim(ComboBox2.Text),trim(edit1.text));
  end;
end;


模块文档(详细收费标准版本号,适用四种方式,适用16位、24位、32位登陆密码)。
unit ElAES;
interface
{
改动时间:2014-02-12
设计方案:QQ
启用方式:
1: AES标识符串数据加密
function EncryptString(Value: string; Key: AnsiString;
  KeyBit: TKeyBit = kb128;mode:string='ECB';iv:AnsiString='abcdef'): string;
Value:等数据加密标识符串
Key  :16位\24位\32位的密匙
KeyBit:密匙长短,16标识符的密匙长短挑选12八位, 24标识符的密匙长短挑选192位,32标识符的密匙长短挑选256位
mode:  是ECB\CBC\CFB\OFB 在其中一种.
iv  :  原始化空间向量
回到:回到数据加密后的十六进制标识符串

2:AES优化算法标识符串解密
function DecryptString(Value: string; Key: AnsiString;
  KeyBit: TKeyBit = kb128;mode:string='ECB';iv:AnsiString='abcdef'): string;
Value:为十六进制的数据加密码串(即启用EncryptString后回到的結果)
在其中主要参数同EncryptString的一至.

3:回到Base64码:
function GetBase64():string;//Base64编号
留意:请先启用 EncryptString方式后再启用该方式.
回到数据加密串的Base64编号的标识符串.

}
uses
  Classes, SysUtils;
type
  TKeyBit = (kb128, kb192, kb256);

type
  EAESError = class(Exception);

  PInteger  = ^Integer;


  TAESBuffer = array [0..15] of byte;
  TAESKey128 = array [0..15] of byte;
  TAESKey192 = array [0..23] of byte;
  TAESKey256 = array [0..31] of byte;
  TAESExpandedKey128 = array [0..43] of longword;
  TAESExpandedKey192 = array [0..53] of longword;
  TAESExpandedKey256 = array [0..63] of longword;
  //FCB
  Tw = array [0..59] of integer;
  //w =^Tw;
  Ts = array [0..3,0..3] of integer;
  s=^Ts;

………….

数据加密优化算法:
function encryptCBC(Source:string;const iv:string;Dest: TStream):string;
var
  t,y:string;
  y_block:string;
  xsize:integer;
  I, J,Count: integer;
  val:char;
  TempIn, TempOut: TAESBuffer;
  Done: cardinal;
begin
  result := '';
  t:='';
  y:='';  //returned plain text;
  y_block:=iv;
  xsize:= length(Source);  //12 源字串长短//hello world!
  i:=0;
  while i (xsize)  do
  begin
  t:='';
  for J:=0 to 15 do
  begin
  //$y_block[$j] = chr(ord(($i+$j) $xsize ? $x[$i+$j] : chr(0)) ^ ord($t[$j]));
  if (i+j) xsize then
  begin
  val:=Source[i+j+1];
  end
  else
  begin
  val:=chr(0);
  end;
  t:=t+chr(ord(val) xor ord(y_block[j+1]));
  end;
  y_block:= encryptBlock(t);
  y:=(y) + (y_block);
  INC(i,16);
  end;
  result:=y;
end;

function encryptBlock(x:string):string;
var
  y:string;
  I, J,m,n,o,io,mm,nn: integer;
  Nb:integer;
  s:Ts;
  temp:integer;
  temp1:array [0..100] of integer;
  s0,s1,s2,s3:integer;
begin
  result:='';
  y:='';
  for I := 0 to 3 do
  begin
  for J := 0 to 3 do
  begin
  s[I][J]:=0;
  end;
  end;
  Nb:=4;
  //x数值:string(16) "abcdef"
  //将键入x为原始情况引流矩阵的列次序
  for i:=0 to 4*Nb-1 do
  begin
  s[i mod 4][(i-i mod Nb) div Nb]:=ord(x[i+1]); //大家期待为二级指标值integerger区划
  end;
  //array(4){[0]= { array(4) { [0]= int(49) [1]= int(53) [2]= int(57) [3]= int(99) }
  //  [1]= array(4) { [0]= int(50) [1]= int(54) [2]= int(48) [3]= int(100)}
  //  [2]= array(4) { [0]= int(51) [1]= int(55) [2]= int(97) [3]= int(101)}
  //  [3]= array(4) { [0]= int(52) [1]= int(56) [2]= int(98) [3]= int(102)}
  //}
  //addRoundKey(0);
  temp:=0;
  for i:=0 to 3 do
  begin
  for j:=0 to Nb-1 do
  begin
  temp:=((w[0*Nb+j]) shr ((3-i)*8)); //右移24位数值97
  temp:=temp mod 256;
  if temp 0 then
  begin
  temp:=256 + temp;
  end;
  s[i][j]:=s[i][j] xor temp;
  end;
  end;
  //  array(4) { [0]= array(4) { [0]= int(80) [1]= int(80) [2]= int(80) [3]= int(15) }
  //  [1]= array(4) { [0]= int(80) [1]= int(80) [2]= int(90) [3]=   int(9) }
  //  [2]= array(4) { [0]= int(80)  [1]= int(80) [2]= int(20) [3]= int(11) }
  //  [3]= array(4) { [0]= int(80)  [1]= int(80) [2]= int(9)  [3]= int(9)  }
  //  }

  //////////////////////////////
  for i:=1 to Nr-1 do
  begin
  //$this- subBytes();
  for mm:=0 to 3 do
  begin
  for nn:=0 to Nb-1 do
  begin
  s[mm][nn]:= LastForwardTable[s[mm][nn]];
  end;
  end;
  //array(4) {
  // [0]=   array(4) {  [0]= int(83) [1]= int(83)[2]= int(83) [3]= int(118) }
  // [1]=   array(4) { [0]= int(83) [1]= int(83) [2]= int(190)[3]= int(1)}
  // [2]=   array(4) { [0]= int(83) [1]= int(83) [2]= int(250)[3]= int(43)}
  // [3]=   array(4) { [0]= int(83) [1]= int(83) [2]= int(1)  [3]= int(1)}
  //}
  ////////////////////////////////////////////
  //$this- shiftRows();
  for o:=0 to 100 do
  begin
  temp1[o]:=0;
  end;
  for m:=1 to 3 do
  begin
  for n:=0 to Nb-1 do
  begin
  temp1[n]:=s[m][(n+m) mod Nb];
  end;
  for n:=0 to Nb-1 do
  begin
  s[m][n]:=temp1[n];
  end;
  end;
  //array(4) {
  //  [0]= array(4) {[0]= int(83)[1]= int(83) [2]= int(83)[3]= int(118) }
  //  [1]= array(4) {[0]= int(83)[1]= int(190)[2]= int(1) [3]= int(83) }
  //  [2]= array(4) {[0]= int(250)[1]= int(43) [2]= int(83)[3]= int(83) }
  //  [3]= array(4) {[0]= int(1)  [1]= int(83) [2]= int(83) [3]= int(1) }
  //}
  //////////////////////////////////////////
  //$this- mixColumns();
  s0:=0; s1:=0; s2:=0; s3:=0;
  // There are Nb columns
  for m:=0 to Nb-1 do
  begin
  s0:= s[0][m]; s1:=s[1][m];s2:=s[2][m];s3:=s[3][m];
  //83==83==250==1
  s[0][m]:=mult($02, s0) xor mult($03, s1) xor mult($01, s2)xor mult($01,s3);
  //166 xor  245  xor 250 xor 1
  s[1][m]:=mult($01, s0) xor  mult($02, s1) xor  mult($03, s2) xor  mult($01, s3);
  s[2][m]:=  mult($01, s0) xor  mult($01, s1) xor  mult($02, s2) xor  mult($03,s3);
  s[3][m]:=  mult($03, s0) xor  mult($01, s1) xor  mult($01, s2) xor  mult($02,s3);
  end;
  //array(4) {
  //  [0]= array(4) { [0]= int(168) [1]= int(7)  [2]= int(165) [3]= int(75)}
  //  [1]= array(4) { [0]= int(225) [1]= int(26) [2]= int(247) [3]= int(36)}
  //  [2]= array(4) { [0]= int(236) [1]= int(78) [2]= int(1)  [3]= int(128)}
  //  [3]= array(4) { [0]= int(94)  [1]= int(198)[2]= int(1)  [3]= int(152)}
  //}

 

  ////////////////////////////////////////
  // add round key
  //$this- addRoundKey($i);
  temp:=0;
  for m:=0 to 3 do
  begin
  for n:=0 to Nb-1 do
  begin
  temp:=((w[i*Nb+n]) shr ((3-m)*8));
  temp:=temp mod 256;
  if temp 0 then
  begin
  temp:=256 + temp;
  end;
  s[m][n]:=s[m][n] xor temp;
  end;
  end;
  //刚开始array(4) {
  //  [0]= array(4) { [0]= int(152) [1]= int(51) [2]= int(157) [3]= int(121)  }
  //  [1]= array(4) { [0]= int(208) [1]= int(47) [2]= int(206) [3]= int(23) }
  //  [2]= array(4) { [0]= int(222) [1]= int(120)[2]= int(49)  [3]= int(180)  }
  //  [3]= array(4) { [0]= int(109) [1]= int(241)[2]= int(48) [3]= int(173) }
  //}
  //未尾array(4) {
  //  [0]=   array(4) { [0]= int(159)[1]= int(19) [2]= int(2)  [3]= int(207)}
  //  [1]=   array(4) { [0]= int(31) [1]= int(110)[2]= int(103) [3]= int(151)}
  //  [2]=   array(4) { [0]= int(223)[1]= int(67) [2]= int(160) [3]= int(86) }
  //  [3]=   array(4) { [0]= int(26) [1]= int(32) [2]= int(170) [3]= int(174)}
  //}
  /////////////////////////////////////////
  end;
  io:=i;
  // substitute bytes
  //$this- subBytes();
  for i:=0 to 3 do
  begin
  for j:=0 to Nb-1 do
  begin
  s[i][j] := LastForwardTable[s[i][j]];
  end;
  end;
  //////////////////////////////////////////////////////////
  // shift rows
  //$this- shiftRows();
  for o:=0 to 100 do
  begin
  temp1[o]:=0;
  end;
  for m:=1 to 3 do
  begin
  for n:=0 to Nb-1 do
  begin
  temp1[n]:=s[m][(n+m) mod Nb];
  end;
  for n:=0 to Nb-1 do
  begin
  s[m][n]:=temp1[n];
  end;
  end;
  //////////////////////////////////////////////////////////
  // add round key
  //$this- addRoundKey($i);
  temp:=0;
  for i:=0 to 3 do
  begin
  for j:=0 to Nb-1 do
  begin
  temp:=((w[io*Nb+j]) shr ((3-i)*8));
  temp:=temp mod 256;
  if temp 0 then
  begin
  temp:=256 + temp;
  end;
  s[i][j]:=s[i][j] xor temp;
  end;
  end;
  //////////////////////////////////////////////////////////
  // place state matrix s into y in column order
  for i:=0 to (4*Nb-1) do
  begin
  y:=y+chr(s[i mod 4][(i-i mod Nb) div Nb]);
  end;
  //y='??'#$13'nC '#2'g牚蠗V'#$AE
  //int(159)int(31)int(223)int(26)int(19)int(110)int(67)int(32)int(2)int(103)int(160)int(170)int(207)int(151)int(86)int(174)
  result:=y;
end;

手机软件设计方案

 

非常提醒: 本网站能够给你开展优化算法编程设计, 有详细的AES优化算法编码,  在其中的Delphi撰写的AES优化算法编码是在网上找不着的,假如你必须,能够联络本网站服务QQ. 


 【强烈推荐阅读文章】
手机软件设计方案和企业网站建设对策剖析
贵阳市企业网站建设的网站内部构造提升
用 C# 撰写 AES 类结构涵数
AES对称性数据加密优化算法基本原理详细说明