Turboower Lockbox3 - 可以控制AES-256加密的初始化向量和填充吗? [英] Turbopower Lockbox3 - Can I control initialization vector and padding for AES-256 encryption?

查看:639
本文介绍了Turboower Lockbox3 - 可以控制AES-256加密的初始化向量和填充吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



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)



感谢
Jan

解决方案

a)IV



让我的前言说你可能正在努力解决一个不需要解决的问题。 Lockbox 3是自动盐渍的。这意味着在大多数情况下,会自动生成64位随机数并将其插入到IV中。随机数值通过插入传输到密文流中。结果是,您可以使用TCodec组件,而无需编写单行代码来管理IV,您仍然可以获得所有的盐化加密优点(基本上意味着不可预测的IV)。这与DCPCrypt相反,您可以将IV置零,也可以自行管理IV。



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



如果您想要一些演示代码,请告知我。



b)填充(从第一篇文章更正,对不起错误。)



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




  • 零长度消息



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




  • ECB模式



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




  • 不是ECB,但消息块对齐



无填充。




  • 按键流模式(如OFB)



没有填充。终止由截断处理。




  • 其他(如CBC)



没有填充。终止是由密文盗窃处理的,这是太酷了学校!如果消息对于密文盗取(小于2个块)太短,则会自动切换到CFB-8位,并将其视为密钥流。






更新



警告



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



以下代码片段演示了从评论中给出的测试向量中的LockBox3解密。假设密文流以完整的IV为前缀,加密编解码器使用(yucky)全零填充。

  procedure TForm5.Button1Click(Sender:TObject); 
const
密钥:ansistring =#$ 33#$ d4#$ 6c#$ ff#$ a1#$ 58#$ 53#$ 31#$ 94#$ 21#$ 4a#$ 91#$ e7#$ 12#$ fc#$ 2 b +
#$ 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;
如果Recon_Plaintext = Reference_Plaintext then
ShowMessage('Test passed!LockBox3从CSharp样式的零填充解密')
else
ShowMessage('Test failed!')
结束



有些注意事项:




  1. 假设您已经在设计时预先创建了一个TCodec和TCryptographicLibrary(建议命名),可能在一个表单上。

  2. TCodec的链接模式和其他属性已经设计在设计时。在我们的测试向量的情况下,它应该设置为CBC。

  3. 给定的流到块适配器是一个特殊的,适合于加密库通常不包含的。这就是为什么有一行代码来明确注册它。

  4. 您将需要一个CVS客户端从TurboPower LockBox 3 CVS存储库中下载最新版本。此适配器尚未正式发布。

  5. 使用此适配器,您只能解密。 CSharp兼容加密尚不可用。 (让我知道,如果你需要更早而不是以后)。

  6. 我在Delphi 2007和Delphi 2010中测试了它。它适用于我。

  7. <




    更正



    maxiumum短信长度,即说明文消息的最大长度将被认为对于经典密文流传输来说太短,因此将其链接模式视为密钥流(CFB 8位),比一个块少一个字节(不是少)超过2块')。一个半块消息仍然可以使用密文偷取其块量化方法。一半块消息不能。


    In the process of moving from Delphi2007 to XE2, we are thinking about switching encryption libraries from DCPCrypt to Turbopower Lockbox 3.

    a) In DCPCrypt I have explicit control over the initialization vector. How would I set the IV in TPLB3?

    b) DCPCrypt has no padding, we pad the plaintext with zeroes before encryption. How does TPLB pad? We could still do it ourselves of course.

    Test Vector

    • Cipher = AES-256;
    • Chaining mode = CBC;
    • Termination = C# style all-zero-padding;
    • IV transmission = Full block prepended in the clear in the ciphertext stream.
    • Key = 33d46cffa158533194214a91e712fc2b45b587076675affd910edeca5f41ac64 little-endien
    • IV = 917fe226df8308f4d96c33304768354a
    • Ciphertext = +kdTGzdV5KZIw8tv466nhQ== (base64)
    • Plaintext = 'a_decent_text' (ansistring)

    Thanks Jan

    解决方案

    a) IV

    Let me preface by saying you may be trying to solve a problem that doesn't need solving. Lockbox 3 is auto-salted. That means that under most circumstances a 64 bit nonce is automatically generated and inserted into the IV. The nonce value is transported by means of insertion into the ciphertext stream. The upshot is that you can use the TCodec component without writing single line of code to manage IV's, and you still get all the cryptographic benefits of salting (basically meaning unpredictable IV's). This is in contrast to DCPCrypt, where you either have zeroised IV's or you self-manage the IV's.

    I can't imagine a scenario, other than "Known Test Answer" testing that you would want or need to override this behaviour, but having said that, if you really want to insist on setting your own IV's, if you have a cvs client, you can download revision 231 (not yet "stable release" status), and implement the OnSetIV() event handler of the TCodec component to set the IV to your custom value. As the IV is transmitted with the message, this step is not necessary upon decrypt.

    Let me know if you want some demo code.

    b) Padding (corrected from first post. Sorry for the error.)

    It depends on the chaining method. When the standard stream-to-block adapter is used, termination is handled in the following cases.

    • Zero length messages:

    Zero length messages are encrypted as zero length ciphertext.

    • ECB mode:

    For ECB mode Lockbox 3 uses ISO/IEC 9797-1 method 2 padding. ISO/IEC 9797-1 method 2 essentially is a pad of one byte with value $80 followed by as many zero bytes as required to reach the next block boundary.

    • Not ECB, but message is block aligned:

    No padding. No special termination handling is required.

    • Key-streaming mode (such as OFB)

    No padding. Termination is handled by truncation.

    • Other (such as CBC)

    No padding. Termination is handled by ciphertext stealing, which is "too cool for school"! If the message is too short for ciphertext stealing (less than 2 blocks), then it automatically switches to CFB-8 bit and treat as key-streaming.


    UPDATE

    Caveat

    LockBox 3 was never designed for interoperability with CSharp style user-managed IV and all-zero padding. (IMHO, this type of padding is problematic and should be eschewed).

    The following code fragment demonstrates LockBox3 decrypting from the test vector given in the comments. It is assumed that the ciphertext stream is prepended with the full IV and that the encrypting codec uses (yucky) all-zero padding.

    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;
    

    Some points to note:

    1. It is assumed that you have pre-created a TCodec and TCryptographicLibrary (suggestively named), probably on a form at design time.
    2. The TCodec's chaining mode and other properties have already been set at design time. In the case of our test vector, it should be set to CBC .
    3. The given stream-to-block adapter is a special one, not normally included in the cryptographic library. This is why there is a line of code to explicitly register it.
    4. You will need a CVS client to down-load the latest revision from the TurboPower LockBox 3 CVS repository. This adapter is not yet in the official stable release.
    5. Using this adapter, you can only decrypt. CSharp-compatible encryption is not yet available. (Let me know if you need it sooner rather than later).
    6. I tested it on Delphi 2007 and Delphi 2010. It works for me.


    Correction

    The maxiumum short message length, that is the say the maximum length of plaintext message that will be deemed as too short for classical ciphertext streaming, and so have it's chaining mode treated as a key-streaming one (CFB 8-bit), is one byte less than one block, (not 'less than 2 blocks' as stated earlier). A one and a half block message can still use ciphertext stealing for its block quantisation method. A half block message cannot.

    这篇关于Turboower Lockbox3 - 可以控制AES-256加密的初始化向量和填充吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆