【问题标题】:Turbopower Lockbox3 - Can I control initialization vector and padding for AES-256 encryption?Turbopower Lockbox3 - 我可以控制 AES-256 加密的初始化向量和填充吗?
【发布时间】:2012-06-01 09:30:17
【问题描述】:

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

a) 在 DCPCrypt 中,我对初始化向量有明确的控制。如何在 TPLB3 中设置 IV?

b) DCPCrypt 没有填充,我们在加密前用零填充明文。 TPLB怎么垫?当然,我们仍然可以自己做。

测试向量

  • 密码 = AES-256;
  • 链接模式 = CBC;
  • 终止 = C# 样式全零填充;
  • IV 传输 = 在密文流中以明文形式预先设置完整块。
  • 密钥 = 33d46cffa158533194214a91e712fc2b45b587076675affd910edeca5f41ac64 little-endien
  • IV = 917fe226df8308f4d96c33304768354a
  • 密文 = +kdTGzdV5KZIw8tv466nhQ== (base64)
  • 纯文本 = 'a_decent_text'(辅助字符串)

谢谢 一月

【问题讨论】:

    标签: delphi aes lockbox-3


    【解决方案1】:

    a) IV

    让我先说您可能正在尝试解决一个不需要解决的问题。密码箱 3 是自动加盐的。这意味着在大多数情况下,会自动生成一个 64 位随机数并将其插入 IV。随机数值通过插入密文流的方式传输。结果是您可以使用 TCodec 组件而无需编写单行代码来管理 IV,并且您仍然可以获得加盐的所有加密优势(基本上意味着不可预测的 IV)。这与 DCPCrypt 形成鲜明对比,在 DCPCrypt 中,您要么将 IV 归零,要么自行管理 IV。

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

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

    b) 内边距(已从第一篇文章中更正。对错误深表歉意。)

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

    • 零长度消息

    零长度消息被加密为零长度密文。

    • 欧洲央行模式

    对于 ECB 模式 Lockbox 3 使用 ISO/IEC 9797-1 方法 2 填充。 ISO/IEC 9797-1 方法 2 本质上是一个 80 美元的字节填充,后跟到达下一个块边界所需的零字节。

    • 不是 ECB,但消息是块对齐的

    没有填充。不需要特殊的终止处理。

    • 密钥流模式(例如 OFB)

    没有填充。通过截断处理终止。

    • 其他(例如 CBC)

    没有填充。终止是通过密文窃取来处理的,这“对学校来说太酷了”!如果消息太短而无法窃取密文(小于 2 块),则它会自动切换到 CFB-8 位并视为密钥流。


    更新

    警告

    LockBox 3 从未设计用于与 CSharp 风格的用户管理 IV 和全零填充的互操作性。 (恕我直言,这种类型的填充是有问题的,应该避免使用)。

    以下代码片段演示了如何从 cmets 中给出的测试向量中解密 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;
    

    需要注意的几点:

    1. 假设您在设计时可能在表单上预先创建了 TCodec 和 TCryptographicLibrary(建议命名)。
    2. TCodec 的链接模式和其他属性已在设计时设置。对于我们的测试向量,它应该设置为 CBC。
    3. 给定的流到块适配器是一个特殊的适配器,通常不包含在加密库中。这就是为什么有一行代码可以显式注册它的原因。
    4. 您需要一个 CVS 客户端才能从 TurboPower LockBox 3 CVS 存储库下载最新版本。此适配器尚未正式发布。
    5. 使用此适配器,您只能解密。 CSharp 兼容的加密尚不可用。 (如果您需要,请尽早告诉我)。
    6. 我在 Delphi 2007 和 Delphi 2010 上对其进行了测试。它适用于我。

    更正

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

    【讨论】:

    • 我的 IV 问题来自这样一个事实,即我们必须在 asp.Net 平台上用 C# 加密并在 Delphi Win32 应用程序中解密。两个平台上的参数需要匹配。
    • nonce插入密文是什么意思?我需要一个“裸”密码才能在“另一边”解密它
    • 给我更多信息,我将发布一些关于如何在 Delphi 端控制 IV 的示例代码。 Delphi端是加密还是解密?你使用什么链接模式?什么版本的德尔福?你控制 C# 端,还是由第三方编写?
    • Delphi端解密。 AES-256 CBC 链接,零填充。 C# 端连接 IV+密文,base64 它,并将其作为参数传递给 Delphi 中的 web 服务。 Delphi 代码知道 IV 和密码的大小,因此它可以将它们拆分和解码。然后删除填充的 ASCII 0 以获得明文。正如您在原始答案中所写的那样,填充以 $80 字节开头。
    • C# 加密,我们可以控制:MemoryStream ms = new MemoryStream(); AesManaged aes = new AesManaged(); aes.Padding = PaddingMode.Zeros; aes.GenerateIV(); aes.Key = -something-;当前IV = aes.IV; CryptoStream cs = new CryptoStream(ms, aes.CreateEncryptor(), CryptoStreamMode.Write); cs.Write(input, 0, input.Length); cs.关闭();返回 ms.ToArray();
    猜你喜欢
    • 2014-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-29
    • 1970-01-01
    • 2019-03-03
    相关资源
    最近更新 更多