当前位置: 首页 > 知识库问答 >
问题:

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

夹谷茂
2023-03-14

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

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

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

  • 密码=AES-256;
  • 链接模式=CBC;
  • 终止=C#样式全零填充;
  • IV传输=在密文流中清除前缀的完整块。
  • key=33d46cffa158533194214a91e712fc2b45b587076675affd910edeca5f41ac64 Little-endien
  • IV=917fe226df8308f4d96c33304768354a
  • 密文=kdTGzdV5KZIw8tv466nhQ==(base 64)
  • 纯文本='a_decent_text'(ansistring)

谢谢,简

共有1个答案

龙嘉玉
2023-03-14

a) 四,

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

我无法想象一个场景,除了“已知测试答案”测试,你会想要或需要覆盖这种行为,但是话虽如此,如果你真的想坚持设置自己的静脉注射,如果你有一个简历客户端,你可以下载231版(尚未稳定发布状态),并实现TCodec组件的OnSetIV()事件处理程序,将IV设置为自定义值。由于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;
  1. 假设您已经预先创建了TCodec和TCryptographicLibrary(建议命名),可能是在设计时在表单上创建的
  2. TCodec的链接模式和其他属性已在设计时设置。对于我们的测试向量,它应该设置为CBC
  3. 给定的流到块适配器是一个特殊的适配器,通常不包括在加密库中。这就是为什么有一行代码来显式注册它
  4. 您需要一个CVS客户端从TurboPower LockBox 3 CVS存储库下载最新版本。这个适配器还没有正式的稳定版本
  5. 使用此适配器,您只能解密。CSharp兼容的加密尚不可用。(如果您需要,请尽快告诉我)
  6. 我在Delphi2007和Delphi2010上测试了它。它对我有用

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

 类似资料:
  • 问题内容: 我有一个关于在AES加密中使用初始化向量的问题。我引用以下文章/帖子将加密功能构建到程序中: [1] 基于Java256位AES密码的加密 [2]http://gmailassistant.sourceforge.net/src/org/freeshell/zs/common/Encryptor.java.html 我最初从第一个链接开始关注erickson的解决方案,但是据我所知,我

  • 我使用初始化向量和填充实现了AES 128位加密,如下面的代码所示。我碰巧使用了ColdFusion,但我认为这并不重要。加密结果显示了一些重复模式,这是我没有预料到的,但话说回来,我不知道正确输出的特征。我是否正确地进行了初始化向量和填充? 下面是示例输出: 每个加密字符串都以相同的21个字符结尾: 当原始字符串相同(第3和第4个示例中的“String3”)时,EncryptedString以相

  • 我对我当前尝试访问的API的加密有以下要求: < li>PKCS7填充方法 < li>CBC加密模式 < li>AES密钥大小256,块大小128 每次我提交带有加密的API时,API似乎都有问题(不幸的是没有产生错误)。 问题: PKCS7填充方法到底是什么,可以用php实现? AES 256很好,但是块大小到底是什么意思? IV到底是做什么的?

  • 我有下面的代码,使用我在这里找到的一个简单的面向字节的AES-256库为AES-256 ECB加密工作。 主要: 加密功能: 我想在此程序中添加一个IV以创建AES-256 CBC模式。根据我的理解,IV实现如下: 将第一个块与IV进行异或。 将所有后续块与前一块的密码文本进行异或 我的问题是逻辑是什么样的?我如何将其实现到我的代码中?

  • 我在一个项目中工作,在这个项目中,我通过XML流向web服务发帖。在这种情况下,提供程序请求使用密码块链接(CBC)模式下的高级加密标准(AES)和128位初始化向量对路由xml进行加密。我是用VB.NET编码的,从我可以看出我已经满足了他们所有的加密要求,但当我提交帖子时,我总是得到一个“无效的路由输入加密”的错误响应。我没有做很多与加密,所以我希望有人与一些加密经验可以帮助我在这里。它失败是因

  • 如果公司营业额大于50亿卢比,GST理事会已批准将企业对企业(B2B)发票的“电子发票”或“电子发票”实施到GST系统。参考商品及服务税门户 API :einv-apisandbox.nic.in/index.html 我必须使用APP密钥对加密的SEK进行解密,并使用解密的SEK对json数据进行编码,以便发布Einvoice Generation,我找到了java和C#的示例代码,我已经用PH