a)在DCPCrypt中,我可以明确控制初始化向量.我如何在TPLB3中设置IV?
b)DCPCrypt没有填充,我们在加密前用明文填充明文. TPLB如何填充?我们当然可以自己做.
测试矢量
>密码= AES-256;
>链接模式= CBC;
>终止= C#样式全零填充;
> IV传输=在密文流中以明文形式预先填充的完整块.
> Key = 33d46cffa158533194214a91e712fc2b45b587076675affd910edeca5f41ac64 little-endien
> IV = 917fe226df8308f4d96c33304768354a
>密文= kdTGzdV5KZIw8tv466nhQ ==(base64)
> Plaintext =’a_decent_text'(ansistring)
谢谢
一月
解决方法
让我先说你可能正试图解决一个不需要解决的问题. LockBox 3是自动加盐的.这意味着在大多数情况下会自动生成64位随机数并插入到IV中.通过插入密文流来传输随机数值.结果是您可以使用TCodec组件而无需编写单行代码来管理IV,并且您仍然可以获得salting的所有加密优势(基本上意味着不可预测的IV).这与DCPCrypt形成鲜明对比,在DCPCrypt中,您要么将IV归零,要么自行管理IV.
我无法想象一个场景,除了“已知的测试答案”测试,你想要或需要覆盖这种行为,但话虽如此,如果你真的想坚持设置你自己的IV,如果你有一个cvs客户端,您可以下载修订版231(尚未“稳定版本”状态),并实现TCodec组件的OnSetIV()事件处理程序以将IV设置为您的自定义值.由于IV与消息一起传输,因此在解密时不需要该步骤.
如果你想要一些演示代码,请告诉我.
这取决于链接方法.使用标准的流到块适配器时,在以下情况下处理终止.
>零长度消息:
零长度消息被加密为零长度密文.
> ECB模式:
对于ECB模式,LockBox 3使用ISO / IEC 9797-1方法2填充. ISO / IEC 9797-1方法2本质上是一个字节的填充,其值为$80,后跟到达下一个块边界所需的零字节数.
>不是ECB,但是消息是块对齐的:
没有填充物.无需特殊的终止处理.
>密钥流模式(如OFB)
没有填充物.终止由截断处理.
>其他(如CBC)
没有填充物.终止是由密文窃取处理的,这对学校来说“太酷了”!如果消息对于密文窃取而言太短(少于2个块),则它会自动切换到CFB-8位并视为密钥流.
UPDATE
警告
LockBox 3从未设计用于与CSharp样式的用户管理IV和全零填充的互操作性. (恕我直言,这种类型的填充是有问题的,应该避免).
以下代码片段演示了LockBox3从注释中给出的测试向量进行解密.假设密文流前置有完整的IV,并且加密编解码器使用(令人讨厌的)全零填充.
procedure TForm5.Button1Click(Sender: TObject); const Key: ansistring = #$33#$d4#$6c#$ff#$a1#$58#$53#$31#$94#$21#$4a#$91#$e7#$12#$fc#$2b + #$45#$b5#$87#$07#$66#$75#$af#$fd#$91#$0e#$de#$ca#$5f#$41#$ac#$64; Reference_Plaintext: ansistring = 'a_decent_text'; IV: ansistring = #$91#$7f#$e2#$26#$df#$83#$08#$f4#$d9#$6c#$33#$30#$47#$68#$35#$4a; var Stream,ReconStream: TStream; Cipherb64: ansistring; Recon_Plaintext: ansistring; begin Stream := TMemoryStream.Create; Stream.WriteBuffer( Key[1],Length( Key)); Stream.Position := 0; CryptographicLibrary1.RegisterStreamCipher( StreamToBlock_Adapter_CSharpVariant); Codec1.StreamCipherId := 'CSharp.StreamToBlock'; Codec1.BlockCipherId := Format( AES_ProgId,[256]); Codec1.InitFromStream( Stream); Stream.Size := 0; Stream.WriteBuffer( IV[1],Length( IV)); Cipherb64 := '+kdTGzdV5KZIw8tv466nhQ=='; Base64_to_stream( Cipherb64,Stream); ReconStream := TMemoryStream.Create; Stream.Position := 0; Codec1.DecryptStream( ReconStream,Stream); ReconStream.Position := 0; SetLength( Recon_Plaintext,ReconStream.Size); ReconStream.ReadBuffer( Recon_Plaintext[1],Length( Recon_Plaintext)); SetLength( Recon_Plaintext,StrLen( PAnsiChar( Recon_Plaintext))); ReconStream.Free; Stream.Free; if Recon_Plaintext = Reference_Plaintext then ShowMessage( 'Test passed! LockBox3 decrypts from CSharp-style zero padding.') else ShowMessage( 'Test Failed!') end;
有些要点需要注意:
>假设您已经预先创建了一个TCodec和TCryptographicLibrary(暗示命名),可能在设计时在表单上.
> TCodec的链接模式和其他属性已在设计时设置.在我们的测试向量的情况下,它应该设置为CBC.
>给定的流到块适配器是一个特殊的适配器,通常不包含在加密库中.这就是为什么有一行代码来显式注册它.
>您将需要一个CVS客户端来从TurboPower LockBox 3 CVS存储库下载最新版本.此适配器尚未在官方稳定版本中.
>使用此适配器,您只能解密. CSharp兼容加密尚不可用. (如果您需要早点而不是晚点,请告诉我).
>我在Delphi 2007和Delphi 2010上测试过它.它对我有用.
更正
最大短消息长度,即对于经典密文流将被视为太短的明文消息的最大长度,因此将其链接模式视为密钥流式传输(CFB 8位),是一个小于一个块的字节,(如前所述,不是“少于2个块”).一个半块消息仍然可以使用密文窃取来进行块量化方法.半块消息不能.