我正在使用的代码(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;
它工作得很好,除非我尝试解密字符串,我得到:
所以前几个字母变得非常奇怪。其余部分解密就好了! 发现类似的问题here,但没有解决方案。 提前谢谢!
答案 0 :(得分:5)
对我而言,第一件事就是你在IV的结尾读/写。您将其声明为[0..15],但是从Cipher.Init和SetString开始,从元素1(!)开始访问所有内容。