首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >cipher rijndael delphi 2010 dcp

cipher rijndael delphi 2010 dcp
EN

Stack Overflow用户
提问于 2012-08-11 07:56:05
回答 1查看 975关注 0票数 1

我有一个IV (初始化向量)和密钥,我需要对一个字符串进行循环,这是代码:

代码语言:javascript
复制
function TForm1.CipherAES (key: AnsiString; Vector: AnsiString;
  InStream: TMemoryStream) : TMemoryStream;
var
  cipher: TDCP_rijndael;
  i: integer;
  toEnc, toSnd : array of byte;
  outStream, AStream :TMemoryStream;
  StreamR, Stream2 : AnsiString;
begin
  outStream := TMemoryStream.Create;
  SetLength(toEnc, InStream.Size);

  cipher := TDCP_rijndael.Create(nil);
  cipher.Init(key[1], 128, nil);
  cipher.SetIV(vector[1]);
  cipher.BlockSize := 16;
  InStream.Position := 0;

  for I := 0 to InStream.Size-1 do
    InStream.Read(ToEnc[i], 1);

  for I := 0 to inStream.size-1 do
    StreamR := StreamR + ByteToHex(toEnc[i]) + ' ';
  Memo1.Lines.Add(StreamR);
  inStream.Position := 0;

  cipher.CipherMode := cmCBC;
  cipher.EncryptStream(inStream, outStream, InStream.Size);
  Base64Encode(outStream.Memory, @StreamR[1], outStream.Size);

  Stream2 := Copy(StreamR, 1, outStream.Size + 8);
  Memo1.Lines.Add(Stream2);
  Memo1.Lines.Add(StreamR);

  outStream.Position := 0;

  SetLength(toSnd, outStream.Size);
  for I := 0 to outStream.Size-1 do
    outStream.Read(toSnd[i], 1);

  StreamR := '';
  for I := 0 to outStream.size-1 do
    StreamR := StreamR + ByteToHex(toSnd[i]) + ' ';
  Memo1.Lines.Add(StreamR);

  cipher.burn;
  cipher.free;

  Result := outStream;
end;

当我将流传递给base64时,它会给出下一个答案:

代码语言:javascript
复制
ub/JkCsCZwbAnyqjo+miIw==

但它应该是:

代码语言:javascript
复制
ub/JkCsCZwbAnyqjo+miI2XNZwNrJo31YBNTwQuHkq0=

有人能帮帮我吗?为什么会发生这样的事情?

提前感谢Vauli

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-08-11 23:12:04

如果你对这两个值进行base64解码,你会得到:

ub/JkCsCZwbAnyqjo+miIw==解码为:

代码语言:javascript
复制
B9 BF C9 90 2B 02 67 06-C0 9F 2A A3 A3 E9 A2 23 (in hex) 

=> 16字节

ub/JkCsCZwbAnyqjo+miI2XNZwNrJo31YBNTwQuHkq0=解码为:

代码语言:javascript
复制
B9 BF C9 90 2B 02 67 06-C0 9F 2A A3 A3 E9 A2 23
65 CD 67 03 6B 26 8D F5-60 13 53 C1 0B 87 92 AD (in hex) 

=> 32字节

这让我认为您只向TForm1.CipherAES()传递了16个字节。我之所以这么说,是因为在调用cipher.EncryptStream之后,outStream.size应该等于inStream.size

在使用断点进行测试时,请澄清InStream.Size的值是什么。

在您的代码中添加一些注释:

  1. Base64Encode返回输出缓冲区包含的字节数。您从不使用此值来设置StreamR的大小。

您对base64encode的调用应该类似于:

//为base64解码数据分配缓冲区setLength(StreamR,((inStrem.size + 2) div 3) * 4);size := Base64Encode(outStream.Memory,@StreamR1,outStream.Size);setLength(StreamR,size);

  • 我真的不明白这是什么意思:

Stream2 := Copy(StreamR,1,outStream.Size + 8);

为什么选择outStream.Size + 8?你是不是无视StreamR的实际大小,根据其他缓冲区的大小,从StreamR复制了一些东西?此外,"Copy()“只能获得最大长度(StreamR)字符。

  • 不是一个字节一个字节地填充ToEnc,可以考虑使用:

InStream.ReadBuffer(ToEnc,InStream.size);

对于toSnd也是如此(但.writeBuffer())

关于加密字符串的注意事项(因为我不知道你是如何提供InStream的):

确保加密文本的Unicode版本(UTF16-LE或UTF-8)。将字符串转换为ansiString会通过OS系统区域设置,并可能导致数据丢失(著名的“?”)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11910673

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档