Rijndael 加密。第一个字符很奇怪
我正在使用的代码(XE):
// Encrypt a string and return the Base64 encoded result
function Encrypt(DataToEncrypt: ansistring):ansistring;
const Key: Ansistring = 'keykey';
KeySize = 32; // 32 bytes = 256 bits
BlockSize = 16; // 16 bytes = 128 bits
var
Cipher : TDCP_rijndael;
Data: ansistring;
IV: array[0..15] of byte; // the initialization vector
i:Integer;
begin
// Pad Key, IV and Data with zeros as appropriate
FillChar(IV,Sizeof(IV),0); // make the IV all zeros
Data := PadWithZeros(DataToEncrypt,BlockSize);
for i := 0 to (Length(IV) - 1) do //just random values for the IV
IV[i] := Random(256);
Cipher := TDCP_rijndael.Create(nil);
if Length(Key) <= 16 then
Cipher.Init(Key[1],128,@IV[1])
else if Length(Key) <= 24 then
Cipher.Init(Key[1],192,@IV[1])
else
Cipher.Init(Key[1],256,@IV[1]);
// Encrypt the data
Cipher.EncryptCBC(Data[1],Data[1],Length(Data));
// Free the cipher and clear sensitive information
Cipher.Free;
SetString(InitializationVector,PAnsiChar(@IV[1]),Length(IV)); //Save IV
InitializationVector := Base64EncodeStr(InitializationVector);
//Base64 encoded result
Result := Base64EncodeStr(Data);
end;
function Decrypt(IV,Cryptogram:ansistring):ansistring;
const Key: Ansistring = 'keykey';
KeySize = 32; // 32 bytes = 256 bits
BlockSize = 16; // 16 bytes = 128 bits
var
Cipher : TDCP_rijndael;
begin
if IV='' then
IV := InitializationVector;
Cryptogram := Base64DecodeStr(cryptogram);
// Create the cipher and initialise according to the key length
cipher := tdcp_rijndael.Create(nil);
if Length(Key) <= 16 then
Cipher.Init(Key[1],128,@IV[1])
else if Length(Key) <= 24 then
Cipher.Init(Key[1],192,@IV[1])
else
Cipher.Init(Key[1],256,@IV[1]);
// Decrypt the data
Cipher.DecryptCBC(cryptogram[1],cryptogram[1],Length(cryptogram));
// Free the cipher and clear sensitive information
Cipher.Free;
// Display the result
Result := cryptogram;
end;
它工作得很好,除了当我尝试解密字符串时,我得到:
$C#$C'Ç'#$B'ÛW'#$1F'Ø´™Ç'#$8 D'Ž'#$8D'!'mydata
所以前几个字母会出现非常奇怪的字符。剩下的就解密好了! 此处发现类似问题,但没有解决方案。 提前致谢!
Code i'm using (XE):
// Encrypt a string and return the Base64 encoded result
function Encrypt(DataToEncrypt: ansistring):ansistring;
const Key: Ansistring = 'keykey';
KeySize = 32; // 32 bytes = 256 bits
BlockSize = 16; // 16 bytes = 128 bits
var
Cipher : TDCP_rijndael;
Data: ansistring;
IV: array[0..15] of byte; // the initialization vector
i:Integer;
begin
// Pad Key, IV and Data with zeros as appropriate
FillChar(IV,Sizeof(IV),0); // make the IV all zeros
Data := PadWithZeros(DataToEncrypt,BlockSize);
for i := 0 to (Length(IV) - 1) do //just random values for the IV
IV[i] := Random(256);
Cipher := TDCP_rijndael.Create(nil);
if Length(Key) <= 16 then
Cipher.Init(Key[1],128,@IV[1])
else if Length(Key) <= 24 then
Cipher.Init(Key[1],192,@IV[1])
else
Cipher.Init(Key[1],256,@IV[1]);
// Encrypt the data
Cipher.EncryptCBC(Data[1],Data[1],Length(Data));
// Free the cipher and clear sensitive information
Cipher.Free;
SetString(InitializationVector,PAnsiChar(@IV[1]),Length(IV)); //Save IV
InitializationVector := Base64EncodeStr(InitializationVector);
//Base64 encoded result
Result := Base64EncodeStr(Data);
end;
function Decrypt(IV,Cryptogram:ansistring):ansistring;
const Key: Ansistring = 'keykey';
KeySize = 32; // 32 bytes = 256 bits
BlockSize = 16; // 16 bytes = 128 bits
var
Cipher : TDCP_rijndael;
begin
if IV='' then
IV := InitializationVector;
Cryptogram := Base64DecodeStr(cryptogram);
// Create the cipher and initialise according to the key length
cipher := tdcp_rijndael.Create(nil);
if Length(Key) <= 16 then
Cipher.Init(Key[1],128,@IV[1])
else if Length(Key) <= 24 then
Cipher.Init(Key[1],192,@IV[1])
else
Cipher.Init(Key[1],256,@IV[1]);
// Decrypt the data
Cipher.DecryptCBC(cryptogram[1],cryptogram[1],Length(cryptogram));
// Free the cipher and clear sensitive information
Cipher.Free;
// Display the result
Result := cryptogram;
end;
It works pretty well, except when i try to decrypt the string, i get:
$C#$C'Ç'#$B'ÛW'#$1F'Ø‹™Ç'#$8D'Ž'#$8D'!‘mydata
so first few letters get very weird characters. rest of it is decrypted just fine!
Found similar problem here, but no solution.
Thanks in advance!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
对我来说最突出的第一件事是你正在阅读/写作第四章的结尾。您将其声明为 [0..15],但在 Cipher.Init 和 SetString 中都可以访问从元素 1(!) 开始的所有内容。
The first thing that stands out to me is that you are reading/writing past the end of IV. You declare it as [0..15] but access everything from element 1(!) onwards, both in Cipher.Init and SetString.