Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Ошибка "Invalid key material" при использовании шифрования AES256GCM в Delphi: причины и решения

Delphi , Синтаксис , Шифрование

 

В процессе работы с библиотекой SecureBlackBox в Delphi возникает ошибка "Invalid key material" при попытке расшифровать данные с использованием алгоритма AES256GCM. В этой статье мы рассмотрим возможные причины этой ошибки и предложим решения, которые помогут устранить проблему.

Описание проблемы

Код, который вызывает ошибку, выглядит следующим образом:

function DecryptAES256GCM(aData, aSal, aKey: String): string;

  function Base64UrlDecode(Input: string): TBytes;
  begin
    Result := TNetEncoding.Base64.DecodeStringToBytes(
      StringReplace(
        StringReplace(Input, '-', '+', [rfReplaceAll]),
        '_', '/', [rfReplaceAll]
      )
    );
  end;

var
  Crypto : TElSymmetricCrypto;
  KeyMaterial : TElSymmetricKeyMaterial;
  Factory : TElSymmetricCryptoFactory;
  fIV, fKey, fDataBin, fDataBytes, fDecryptedData : TBytes;
  OutSize : integer;
  Data: RawByteString;
  KeyBinary, IVBinary : ByteArray;
begin
  result := '';

  fDataBin    := Base64UrlDecode(aData);
  fIV         := Base64UrlDecode(aSal);
  fKey        := Base64UrlDecode(aKey);

  SetLength(IVBinary, Length(fIV) * SizeOf(Char));
  Move(Pointer(fIV)^, IVBinary[0], Length(IVBinary));

  SetLength(KeyBinary, Length(fKey) * SizeOf(Char));
  Move(Pointer(fKey)^, KeyBinary[0], Length(KeyBinary));

  SetLength(fDataBytes, Length(fDataBin));
  Move(fDataBin[0], fDataBytes[0], Length(fDataBytes));

  Factory := TElSymmetricCryptoFactory.Create;
  Crypto  := Factory.CreateInstance(SB_ALGORITHM_CNT_AES256, cmGCM);  // <-- Error
  try
    KeyMaterial     := TElSymmetricKeyMaterial.Create;
    KeyMaterial.Key := KeyBinary;
    KeyMaterial.IV  := IVBinary;
    Crypto.Padding  := cpNone;

    Crypto.KeyMaterial := KeyMaterial;
    try
      OutSize := 0;
      Crypto.Decrypt(@fDataBytes[0], Length(fDataBytes), nil, OutSize);
      if OutSize < 0 then
        raise Exception.Create('Failed to decrypt data');

      SetLength(fDecryptedData, OutSize);
      Crypto.Decrypt(@fDataBytes[0], Length(fDataBytes), @fDecryptedData[0], OutSize);
      if OutSize < 0 then
        raise Exception.Create('Failed to decrypt data');

      SetLength(fDecryptedData, OutSize);

      result := TEncoding.UTF8.GetString(fDecryptedData);
    except
      on E: Exception do
        ShowMessage(E.Message);
    end;
  finally
    Factory.Free;
    Crypto.Free;
    KeyMaterial.Free;
  end;
end;

При вызове Crypto.Decrypt возникает исключение "Invalid key material". Это означает, что ключ или вектор инициализации (IV) не соответствуют требованиям алгоритма AES256GCM.

Возможные причины ошибки

  1. Неверная длина ключа или IV:
  2. Алгоритм AES256GCM требует, чтобы длина ключа была 256 бит (32 байта).
  3. Длина IV также должна быть 12 байт для AES256GCM.

  4. Неправильное преобразование данных:

  5. При преобразовании строковых данных в бинарные массивы может происходить потеря данных или их искажение.

  6. Неправильное использование библиотеки SecureBlackBox:

  7. Некорректные настройки объектов, связанных с шифрованием, могут привести к ошибкам.

Решение проблемы

Для устранения ошибки необходимо убедиться, что ключ и IV имеют правильные размеры и что данные корректно преобразованы. Давайте рассмотрим шаги для исправления кода.

  1. Правильное преобразование ключа и IV:
  2. Убедитесь, что длина ключа и IV соответствует требованиям алгоритма AES256GCM.
  3. Используйте функцию Base64UrlDecode для преобразования строковых данных в бинарные массивы.
function Base64UrlDecode(Input: string): TBytes;
begin
  Result := TNetEncoding.Base64.DecodeStringToBytes(
    StringReplace(
      StringReplace(Input, '-', '+', [rfReplaceAll]),
      '_', '/', [rfReplaceAll]
    )
  );
end;
  1. Установка правильных размеров ключа и IV:
  2. Убедитесь, что длина ключа равна 32 байтам (256 битам).
  3. Убедитесь, что длина IV равна 12 байтам.
SetLength(KeyBinary, 32);  // 256 бит = 32 байта
SetLength(IVBinary, 12);   // 96 бит = 12 байт
  1. Исправление ошибок в коде:
  2. Убедитесь, что все переменные корректно инициализированы и что используется правильный размер данных.
function DecryptAES256GCM(aData, aSal, aKey: String): string;
var
  Crypto : TElSymmetricCrypto;
  KeyMaterial : TElSymmetricKeyMaterial;
  Factory : TElSymmetricCryptoFactory;
  fIV, fKey, fDataBin, fDataBytes, fDecryptedData : TBytes;
  OutSize : integer;
begin
  result := '';

  fDataBin    := Base64UrlDecode(aData);
  fIV         := Base64UrlDecode(aSal);
  fKey        := Base64UrlDecode(aKey);

  // Установка правильных размеров для ключа и IV
  SetLength(KeyBinary, 32);  // 256 бит = 32 байта
  SetLength(IVBinary, 12);   // 96 бит = 12 байт

  Move(Pointer(fIV)^, IVBinary[0], Length(IVBinary));
  Move(Pointer(fKey)^, KeyBinary[0], Length(KeyBinary));

  SetLength(fDataBytes, Length(fDataBin));
  Move(fDataBin[0], fDataBytes[0], Length(fDataBytes));

  Factory := TElSymmetricCryptoFactory.Create;
  Crypto  := Factory.CreateInstance(SB_ALGORITHM_CNT_AES256, cmGCM);
  try
    KeyMaterial     := TElSymmetricKeyMaterial.Create;
    KeyMaterial.Key := KeyBinary;
    KeyMaterial.IV  := IVBinary;
    Crypto.Padding  := cpNone;

    Crypto.KeyMaterial := KeyMaterial;
    try
      OutSize := 0;
      Crypto.Decrypt(@fDataBytes[0], Length(fDataBytes), nil, OutSize);
      if OutSize < 0 then
        raise Exception.Create('Failed to decrypt data');

      SetLength(fDecryptedData, OutSize);
      Crypto.Decrypt(@fDataBytes[0], Length(fDataBytes), @fDecryptedData[0], OutSize);
      if OutSize < 0 then
        raise Exception.Create('Failed to decrypt data');

      SetLength(fDecryptedData, OutSize);

      result := TEncoding.UTF8.GetString(fDecryptedData);
    except
      on E: Exception do
        ShowMessage(E.Message);
    end;
  finally
    Factory.Free;
    Crypto.Free;
    KeyMaterial.Free;
  end;
end;

Альтернативное решение

Если проблема не устраняется, можно рассмотреть использование альтернативных библиотек для шифрования, таких как OpenSSL или CryptoLib. Эти библиотеки предоставляют более простой интерфейс и могут быть полезны для разработки приложений на Delphi.

Пример использования OpenSSL для шифрования данных:

uses
  OpenSSL;

function DecryptAES256GCM(aData, aSal, aKey: String): string;
var
  ctx: POpenSSL_CTX;
  key: PByte;
  iv: PByte;
  data: PByte;
  outData: PByte;
  outSize: Integer;
begin
  // Инициализация контекста
  ctx := OpenSSL_CTX_new(EVP_get_cipherbyname('aes-256-gcm'));

  // Преобразование данных
  key := Base64UrlDecode(aKey);
  iv := Base64UrlDecode(aSal);
  data := Base64UrlDecode(aData);

  // Расшифровка данных
  outSize := 0;
  EVP_DecryptInit_ex(ctx, EVP_aes_256_gcm(), nil, key, iv);
  EVP_DecryptUpdate(ctx, outData, @outSize, data, Length(data));
  EVP_DecryptFinal_ex(ctx, outData + outSize, nil);

  // Преобразование в строку
  result := TEncoding.UTF8.GetString(outData, outSize);
end;

Заключение

Ошибка "Invalid key material" при использовании шифрования AES256GCM в Delphi может быть вызвана неверной длиной ключа или IV, неправильным преобразованием данных или неправильным использованием библиотеки SecureBlackBox. Убедитесь, что ключ и IV имеют правильные размеры и что данные корректно преобразованы. В случае необходимости рассмотрите использование альтернативных библиотек для шифрования, таких как OpenSSL или CryptoLib.

Надеюсь, эта статья поможет вам устранить проблему и успешно использовать шифрование AES256GCM в своих проектах на Delphi.

Создано по материалам из источника по ссылке.

Статья описывает причины и решения ошибки "Invalid key material" при расшифровке данных с помощью AES256GCM в библиотеке SecureBlackBox в Delphi, включая проверку длины ключа и IV, правильное преобразование данных и альтернативные библиотеки для шифрован


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.


:: Главная :: Шифрование ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-12-22 20:14:06
2025-04-04 03:07:59/0.015258073806763/0