Я часами борюсь с очень странным явлением. Прежде всего, я использую библиотеку шифрования TurboPower LockBox v10 (с использованием TLbRijndael
), но я Я не уверен, что виноват. Мне нужно передать ключ в функции шифрования / дешифрования, поэтому, естественно, я создал такие функции:
function EncryptText(const S: String; const Key: String): String;
function DecryptText(const S: String; const Key: String): String;
Как ни странно, хотя шифрование кажется работает, когда я пытаюсь расшифровать, он возвращает полный мусор. Итак, во время моего многочасового путешествия в поисках причины то, что я обнаружил, меня совершенно сбивает с толку. Когда я использую ключ шифрования, определенный как константа, все работает. Но при передаче того же значения (также system.string
) в качестве параметра функции это не так.
Итак, чтобы резюмировать это:
- При передаче ключа как константы (
system.string
) все работает нормально. - При передаче ключа в качестве параметра (
system.string
) результаты являются случайными и неверными (и не могут быть расшифрованы).
Вот демонстрация, которую я собрал, чтобы показать, что происходит (мое третье тестовое приложение пытается это понять):
program EncDecDemo;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.Classes, System.SysUtils,
LbCipher, LbClass, LbAsym, LbRSA;
const
ENC_KEY = 'abcdefghijklmnopqrstubwxyz123456';
var
EncComp: TLbRijndael;
function EncAsConst(const S: String): String;
begin
EncComp.SetKey(ENC_KEY); //<-- works as expected
Result:= EncComp.EncryptString(S);
end;
function DecAsConst(const S: String): String;
begin
EncComp.SetKey(ENC_KEY); //<-- works as expected
Result:= EncComp.DecryptString(S);
end;
function EncAsParam(const S: String; const Key: String): String;
begin
EncComp.SetKey(Key); //<-- produces random results
Result:= EncComp.EncryptString(S);
end;
function DecAsParam(const S: String; const Key: String): String;
begin
EncComp.SetKey(Key); //<-- produces random results
Result:= EncComp.DecryptString(S);
end;
var
InputStr: String;
EncrStr: String;
DecrStr: String;
Ctr: Integer;
begin
EncComp:= TLbRijndael.Create(nil);
try
EncComp.Encoding:= TEncoding.UTF8;
EncComp.KeySize:= ks256;
WriteLn('Enter a string to encrypt: ');
ReadLn(Input, InputStr);
WriteLn;
WriteLn('Encrypting as constants...');
EncrStr:= EncAsConst(InputStr);
DecrStr:= DecAsConst(EncrStr);
WriteLn('Pass 1: Enc = '+EncrStr+' Dec = '+DecrStr);
EncrStr:= EncAsConst(InputStr);
DecrStr:= DecAsConst(EncrStr);
WriteLn('Pass 2: Enc = '+EncrStr+' Dec = '+DecrStr);
EncrStr:= EncAsConst(InputStr);
DecrStr:= DecAsConst(EncrStr);
WriteLn('Pass 3: Enc = '+EncrStr+' Dec = '+DecrStr);
WriteLn;
WriteLn('Encrypting as parameters...');
EncrStr:= EncAsParam(InputStr, ENC_KEY);
WriteLn('Pass 1: Enc = '+EncrStr);
EncrStr:= EncAsParam(InputStr, ENC_KEY);
WriteLn('Pass 2: Enc = '+EncrStr);
EncrStr:= EncAsParam(InputStr, ENC_KEY);
WriteLn('Pass 3: Enc = '+EncrStr);
EncrStr:= EncAsParam(InputStr, ENC_KEY);
WriteLn('Pass 4: Enc = '+EncrStr);
EncrStr:= EncAsParam(InputStr, ENC_KEY);
WriteLn('Pass 5: Enc = '+EncrStr);
EncrStr:= EncAsParam(InputStr, ENC_KEY);
WriteLn('Pass 6: Enc = '+EncrStr);
WriteLn;
WriteLn('Press enter to exit');
ReadLn;
finally
EncComp.Free;
end;
end.
Как видите, при передаче одного и того же значения в качестве параметра функции каждый раз результат меняется. Повторяю, точно такое же значение.
Мой единственный вывод состоит в том, что system.string
при использовании в качестве константы (const ENC_KEY = 'value';
) каким-то образом имеет другой размер или тип за кулисами, чем при использовании в качестве переменной.
Когда я заглядываю внутрь SetKey
процедуры, это простой Move
вызов ...
procedure TLbRijndael.SetKey(const Key);
begin
Move(Key, FKey, FKeySizeBytes);
end;
(где FKey
равно array [0..31] of Byte;
)
Что здесь не так и как решить?