由于近来要看算法, 在网上找了几个Delphi写的AES源码,其中一个在各大下载站是最常见的,由ElASE.pas和AES.pas构成,其中主要实现文件EIASE.PAS作者EldoS, Alexander Ionov,AES.PAS实现了AES算法的接口;另外下的一个演示程序实际上主要文件也是EIASE.PAS,不过是繁体的,可能是台湾那边的。两个程序得到的结果相同,但是却让初看AES算法的我很迷惑,因为"this is a test!"这样一个16字符128位的明文,用这两个程序得到的结果密文居然是(16进制数据显示的)“10000000000000005F7DF0BF103A8C4AE6FAAD9906AC3B2A”,转回字节就是24字符了,而按照AES算法,得到的结果应该是16字节的。尝试随意用几段明文作加密,得到的结果前面都会有一堆的000,这是什么原因呢?按理说结果中不会有这些的。
经过跟踪分析,原来在AES.PAS中的加密函数中有这么一段代码
[code]
begin
OutStrm := TStream.Create;
Stream.Position := 0;
Count := Stream.Size;
OutStrm.Write(Count, SizeOf(Count));
try
{ -- 128 位密匙最大长度为 16 个字符 -- }
if KeyBit = kb128 then
[/code]
解密函数中也有一段
[code]
begin
OutStrm := TStream.Create;
Stream.Position := 0;
OutPos :=OutStrm.Position;
Stream.ReadBuffer(Count, SizeOf(Count));
try
{ -- 128 位密匙最大长度为 16 个字符 -- }
if KeyBit = kb128 then
[/code]
注意到 DS.WriteBuffer(Size, SizeOf(Size));就是说在初始化DS这个TStringStream后,接口程序会首先把明文的长度占用长度的类型长度(sizeof(size))写入ds的首部,以致后来转化成密文后再转成十六进制字符显示时会把这个长度信息也输出了,但这个显示不属于AES算法本身范围内,当然最奇怪的是那个繁体版的演示程序也是如此处理了,本来实现的主程序EIASE.PAS是没有任何问题的。
现在初步的解决办法就是把 OutStrm.Write(Count, SizeOf(Count));和Stream.ReadBuffer(Count, SizeOf(Count));注释掉。这样得到的密文就应该是正确的了。