我有一个IV(初始化向量)和密钥,我需要加密一个字符串这是代码:
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时,我给出了下一个答案:
ub/JkCsCZwbAnyqjo+miIw==
但它应该是:
ub/JkCsCZwbAnyqjo+miI2XNZwNrJo31YBNTwQuHkq0=
有人可以帮帮我吗?为什么这样的事情会发生?
提前谢谢
Vauli
答案 0 :(得分:1)
如果你对这两个值进行base64解码,你会得到:
ub / JkCsCZwbAnyqjo + miIw ==解码为:
B9 BF C9 90 2B 02 67 06-C0 9F 2A A3 A3 E9 A2 23 (in hex)
=> 16字节
ub / JkCsCZwbAnyqjo + miI2XNZwNrJo31YBNTwQuHkq0 =解码为:
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字节
这让我觉得你只传递16个字节到TForm1.CipherAES()。 我这样说,因为在调用cipher.EncryptStream之后,outStream.size应该等于inStream.size
请在使用断点进行测试时说明InStream.Size的值是什么。
关于代码的一些注意事项:
Base64Encode返回输出缓冲区包含的字节数。 您永远不会使用此值来设置StreamR的大小。
您对base64encode的调用应该类似于:
// Allocate buffer for base64 decoded data
setLength(StreamR, ((inStrem.size + 2) div 3) * 4);
size := Base64Encode(outStream.Memory, @StreamR[1], outStream.Size);
setLength(StreamR, size);
我真的不明白这个意思:
Stream2:=复制(StreamR,1, outStream.Size + 8);
为什么选择outStream.Size + 8?你正在从StreamR复制一些东西, 基于其他缓冲区的大小,无视您的实际大小 StreamR? “Copy()”也只能获得最多LENGTH(StreamR)字符。
考虑使用:
,而不是逐字节填充ToEncInStream.ReadBuffer(ToEnc [0],InStream.size);
toSnd(但.writeBuffer())
关于加密字符串的注意事项(因为我不知道你如何提供InStream):
确保您正在加密文本的Unicode版本(UTF16-LE或UTF-8)。将字符串转换为ansiString是通过OS系统区域设置进行的,可能导致数据丢失(着名的'????')