В данной статье мы рассмотрим проблему, связанную с обработкой пустого ключа или пароля в алгоритмах Key Derivation Function (KDF) в библиотеке Delphi Encryption Compendium (DEC). Мы рассмотрим текущее состояние проблемы, предложим решение, а также обсудим альтернативные подходы для улучшения безопасности и надежности при работе с KDF в Delphi.
Введение
Ключевое значение KDF заключается в том, что они используются для генерации ключей на основе исходного материала, такого как пароли или случайные значения. В DEC, алгоритмы KDF (например, KDF1, KDF2 и KDF3) предназначены для генерации ключей из данных, которые могут включать пароли, случайные значения и сиды (seed). Однако, как было обнаружено, при передаче пустого ключа или пароля (пустой строки или пустого массива байтов) в функции KDF, возникают проблемы, которые могут привести к непредсказуемым результатам или ошибкам.
Анализ проблемы
В исходном коде DEC, в функции TDECHashAuthentication.KDF1, есть условие, которое проверяет, является ли Seed пустым. Если Seed пуст, то используется пустая строка для инициализации KDF. Однако, если Data (входные данные, такие как пароль или ключ) также пустой, то возникает проблема, так как Data может быть nil, что приводит к ошибке при попытке обратиться к его элементам.
Пример кода, где возникает проблема:
class function TDECHashAuthentication.KDF1(const Data, Seed: TBytes;
MaskSize: Integer): TBytes;
begin
if (length(Seed) > 0) then
Result := KDFInternal(Data[0], length(Data), Seed[0], length(Seed), MaskSize, ktKDF1)
else
Result := KDFInternal(Data[0], length(Data), NullStr, 0, MaskSize, ktKDF1);
end;
В функции KDFInternal, есть несколько вызовов HashInstance.Calc(Data, DataSize), где Data может быть nil. Это приводит к ошибке, так как Data не может быть nil.
Предложенное решение
Для решения данной проблемы, можно внести следующие изменения в код:
Проверка на пустоту входных данных: Добавить проверку на пустоту входных данных Data и Seed. Если Data или Seed пустые, то использовать пустую строку или фиксированный сид для инициализации KDF.
Использование фиксированного сида для пустых данных: В случае, если Data или Seed пустые, использовать фиксированный сид (например, NullStr или другой заранее определенный сид). Это позволит избежать ошибок и обеспечит более предсказуемое поведение.
Пример кода с внесенными изменениями:
class function TDECHashAuthentication.KDF1(const Data, Seed: TBytes;
MaskSize: Integer): TBytes;
begin
if (length(Seed) > 0) then
Result := KDFInternal(Data[0], length(Data), Seed[0], length(Seed), MaskSize, ktKDF1)
else
Result := KDFInternal(Data[0], length(Data), NullStr, 0, MaskSize, ktKDF1);
end;
function TDECHashAuthentication.KDFInternal(const Data, Seed: TBytes;
MaskSize: Integer; KDFType: TKDFType): TBytes;
var
I, n,
Rounds, DigestBytes : Integer;
Count : UInt32;
HashInstance : TDECHashAuthentication;
begin
SetLength(Result, 0);
DigestBytes := DigestSize;
Assert(MaskSize >= 0);
Assert(DataSize >= 0);
Assert(SeedSize >= 0);
Assert(DigestBytes >= 0);
HashInstance := TDECHashAuthenticationClass(self).Create;
try
Rounds := (MaskSize + DigestBytes - 1) div DigestBytes;
SetLength(Result, Rounds * DigestBytes);
if (KDFType = ktKDF2) then
n := 1
else
n := 0;
for I := 0 to Rounds-1 do
begin
Count := SwapUInt32(n);
HashInstance.Init;
if (KDFType = ktKDF3) then
begin
HashInstance.Calc(Count, SizeOf(Count));
if (DataSize > 0) then
HashInstance.Calc(Data, DataSize);
end
else
begin
if (DataSize > 0) then
HashInstance.Calc(Data, DataSize);
HashInstance.Calc(Count, SizeOf(Count));
end;
if (SeedSize > 0) then
HashInstance.Calc(Seed, SeedSize);
HashInstance.Done;
Move(HashInstance.Digest[0], Result[(I) * DigestBytes], DigestBytes);
end;
finally
HashInstance.Free;
end;
end;
В данном примере, мы добавили проверку на пустоту Data и Seed перед вызовом HashInstance.Calc. Если Data или Seed пустые, то вызов HashInstance.Calc пропускается, что предотвращает ошибки.
Альтернативное решение
Вместо использования KDF для генерации ключей из пустых данных, можно рассмотреть использование более современных и безопасных методов, таких как PBKDF2 или Argon2. Эти методы специально разработаны для генерации ключей из паролей и других источников низкой энтропии. Они включают многочисленные раунды хеширования, что обеспечивает дополнительную защиту от атаки на основе словарей и других методов.
В данной статье мы рассмотрели проблему, связанную с обработкой пустых ключей или паролей в алгоритмах KDF в библиотеке DEC. Мы предложили решение, которое включает проверку на пустоту входных данных и использование фиксированного сида для пустых данных. Также мы обсудили альтернативное решение, которое предполагает использование более современных и безопасных методов, таких как PBKDF2 или Argon2.
Разработчики, использующие DEC, могут применить предложенные изменения для улучшения надежности и безопасности своих приложений.
Контекст статьи — анализ и решение проблемы обработки пустых ключей или паролей в алгоритмах KDF библиотеки DEC, включая предложенные корректировки и альтернативные методы для повышения безопасности.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.