Delphi 11中Mormot AES OFB模式加解密结果不一致问题排查
核心问题:Key/IV的实际传递未保持固定,或TAESOFB初始化逻辑未正确使用硬编码值
以下是最可能的几种错误场景:
硬编码Key/IV的类型转换错误
若你将字符串形式的Key/IV转换为TBytes时使用了TEncoding.Default,不同系统环境或重启后的编码差异(比如系统区域设置变化)会导致最终字节数组内容不一致。AES要求Key/IV必须是固定字节序列,必须使用**固定编码(如UTF-8)**或直接用十六进制转字节数组,确保每次转换结果完全相同。未正确设置TAESOFB的IV属性
Mormot的TAESOFB如果创建时未显式传入正确IV,或后续未手动赋值IV属性,默认会自动生成随机IV。即便你以为硬编码了IV,但如果代码中没有将其正确传递给加密对象,每次重启程序后都会生成新的随机IV,导致OFB模式下密文完全不同,自然无法解密之前的结果。Key/IV长度不符合AES-256 OFB的要求
AES-256要求Key必须是32字节(256位),OFB模式的IV必须是16字节(128位)。如果你的硬编码Key/IV长度不足,Mormot的加密对象可能会自动填充或截断,若填充内容不是固定值(比如误用随机填充),就会导致每次重启后实际使用的Key/IV不一致。
验证与修复步骤
检查Key/IV的字节长度
确保硬编码的Key转换为TBytes后长度是32字节,IV转换后是16字节。可以用Length()函数在代码中输出验证,示例代码:const cKeyHex = '00112233445566778899AABBCCDDEEFF00112233445566778899AABBCCDDEEFF'; // 32字节十六进制字符串 cIVHex = '00112233445566778899AABBCCDDEEFF'; // 16字节十六进制字符串 var KeyBytes, IVBytes: TBytes; begin KeyBytes := HexToBin(cKeyHex); IVBytes := HexToBin(cIVHex); // 验证Length(KeyBytes)应为32,Length(IVBytes)应为16 end;显式初始化TAESOFB并传递固定Key/IV
创建TAESOFB实例时,直接传入固定字节数组而非字符串,避免编码转换问题,示例代码:var AES: TAESOFB; PlainText, CipherText, DecryptedText: TBytes; begin AES := TAESOFB.Create(KeyBytes, IVBytes); try CipherText := AES.Encrypt(PlainText); DecryptedText := AES.Decrypt(CipherText); finally AES.Free; end; end;加密前重置加密对象状态
如果复用TAESOFB实例,每次加密前必须重置IV为硬编码值(OFB模式下IV会作为计数器被修改),确保每次加密的初始IV一致:AES.IV := IVBytes; // 加密前强制重置IV CipherText := AES.Encrypt(PlainText);
内容的提问来源于stack exchange,提问作者Zhe

