Delphi Turbopower Lockbox3-我可以控制AES-256加密的初始化向量和填充吗?

Delphi Turbopower Lockbox3-我可以控制AES-256加密的初始化向量和填充吗?,delphi,aes,lockbox-3,Delphi,Aes,Lockbox 3,在从Delphi2007迁移到XE2的过程中,我们正在考虑将加密库从DCPCrypt切换到Turbopower Lockbox 3 a) 在DCPCrypt中,我可以显式控制初始化向量。如何在TPLB3中设置IV b) DCPCrypt没有填充,我们在加密之前用零填充明文。TPLB垫是如何安装的?当然,我们仍然可以自己做 测试向量 密码=AES-256 链接模式=CBC 终止=C#样式所有零填充 IV传输=密文流中在清除中预先设置的完整块 键=33D46CFFA15853194214A91E7

在从Delphi2007迁移到XE2的过程中,我们正在考虑将加密库从DCPCrypt切换到Turbopower Lockbox 3

a) 在DCPCrypt中,我可以显式控制初始化向量。如何在TPLB3中设置IV

b) DCPCrypt没有填充,我们在加密之前用零填充明文。TPLB垫是如何安装的?当然,我们仍然可以自己做

测试向量
  • 密码=AES-256
  • 链接模式=CBC
  • 终止=C#样式所有零填充
  • IV传输=密文流中在清除中预先设置的完整块
  • 键=33D46CFFA15853194214A91E712FC2B45B587076675AFFD910EDECA5F41AC64小端
  • IV=917fe226df8308f4d96c33304768354a
  • 密文=+kdTGzdV5KZIw8tv466nhQ==(基本64)
  • 纯文本='a_delegate_text'(ansistring)
谢谢 一月四日

让我先说一句,你可能正试图解决一个不需要解决的问题。锁盒3是自动腌制的。这意味着在大多数情况下,64位nonce会自动生成并插入到IV中。nonce值通过插入到密文流中来传输。结果是,您可以使用TCodec组件,而无需编写一行代码来管理IV,并且仍然可以获得salt的所有加密好处(基本上意味着不可预测的IV)。这与DCPCrypt形成对比,在DCPCrypt中,您可以将IV归零,也可以自行管理IV

除了“已知测试答案”测试之外,我无法想象有什么场景是您想要或需要覆盖此行为的,但是我已经说过,如果您真的想坚持设置自己的IV,如果您有cvs客户端,您可以下载修订版231(尚未“稳定发布”状态),并实现OnSetIV()用于将IV设置为自定义值的TCodec组件的事件处理程序。由于IV与消息一起传输,因此解密后不需要此步骤

如果你想要一些演示代码,请告诉我

b)填充(从第一篇文章中更正。很抱歉出现错误。)

这取决于链接方法。使用标准流到块适配器时,在以下情况下处理终止

  • 零长度消息
长度为零的消息被加密为长度为零的密文

  • 欧洲央行模式
对于ECB模式,锁盒3使用ISO/IEC 9797-1方法2填充。ISO/IEC 9797-1方法2本质上是一个由一个字节组成的pad,值为$80,后跟达到下一个块边界所需的尽可能多的零字节

  • 不是ECB,但消息是块对齐的
没有填充物。不需要特殊的终端处理

  • 按键流模式(如OFB)
没有填充物。终止由截断处理

  • 其他(如CBC)
没有填充物。终止由密文窃取处理,这对学校来说太酷了!如果消息对于密文窃取来说太短(少于2个块),那么它会自动切换到CFB-8位,并将其视为密钥流


更新 警告 锁盒3从未设计为与CSharp风格的用户管理IV和全零填充互操作。(IMHO,这种类型的填充是有问题的,应该避免)

下面的代码片段演示如何从注释中给出的测试向量解密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兼容的加密尚不可用。(如果您需要,请尽快告诉我)
  • 我在Delphi2007和Delphi2010上测试了它。它对我有用

  • 校正
    最大短消息长度,也就是说,对于经典密文流来说,被认为太短的明文消息的最大长度,因此其链接模式被视为密钥流模式(CFB 8位),比一个块小一个字节(如前所述,“不小于2个块”)。一个一个半块的消息仍然可以使用密文窃取作为其块量化方法。不能使用半块消息

    我的第四个问题来自这样一个事实:我们必须在asp.Net平台上用C#加密,在Delphi Win32应用程序中解密。两个平台上的参数都需要匹配。将nonce插入密文是什么意思?我需要一个'裸'密码,以便能够在'另一边'给我一些更多的信息,我会发布一些关于如何控制你的德尔福方面的静脉注射的示例代码。Delphi端是加密还是解密?您使用什么链接模式?什么版本的Delphi?您是控制C#端还是由第三方编写的?Delphi端解密。AES-256 CBC链接,零填充。C#side将IV+密文连接起来,并将其作为参数传递给Delphi中的webservice。Delphi代码知道IV和cipher的大小,因此可以将它们拆分并解码。然后删除填充ASCII 0