Вопрос или проблема
Я работаю над расшифровкой данных потока WhatsApp с использованием шифрования AES-GCM
на C#, но сталкиваюсь с проблемой при попытке расшифровки данных потока. Ниже приведен мой класс Decryptor, который обрабатывает как расшифровку ключа AES, так и данных потока:
public class Decryptor
{
public static DecryptedRequest DecryptRequest(EncryptedRequest body, string privatePem, string passphrase)
{
Log.Information("Расшифровка запроса с телом: {Bodyinitial_vector}", body.initial_vector);
byte[] encryptedAesKey = Convert.FromBase64String(body?.encrypted_aes_key);
byte[] encryptedFlowData = Convert.FromBase64String(body?.encrypted_flow_data);
byte[] initialVector = Convert.FromBase64String(body?.initial_vector);
byte[] decryptedAesKey;
try
{
// Расшифровка ключа AES с использованием закрытого ключа
using (var rsa = CreateRsaPrivateKey(privatePem, passphrase))
{
decryptedAesKey = rsa.Decrypt(encryptedAesKey, RSAEncryptionPadding.OaepSHA256);
Log.Information("Расшифрованный ключ AES: {decryptedAesKey}", decryptedAesKey);
}
}
catch (Exception ex)
{
throw new FlowEndpointException(421, "Не удалось расшифровать запрос. Пожалуйста, проверьте ваш закрытый ключ.");
}
const int TAG_LENGTH = 16;
byte[] flowDataBuffer = encryptedFlowData;
byte[] initialVectorBuffer = initialVector;
byte[] encryptedFlowDataBody = flowDataBuffer[..^TAG_LENGTH];
byte[] encryptedFlowDataTag = flowDataBuffer[^TAG_LENGTH..];
byte[] decryptedData;
try
{
using (var aesGcm = new AesGcm(decryptedAesKey))
{
decryptedData = new byte[encryptedFlowDataBody.Length];
aesGcm.Decrypt(initialVectorBuffer, encryptedFlowDataBody, decryptedData, encryptedFlowDataTag);
}
}
catch (CryptographicException ex)
{
Log.Error("Ошибка расшифровки: {ErrorMessage}", ex.Message);
throw new FlowEndpointException(400, "Не удалось расшифровать запрос.");
}
string decryptedJSONString = Encoding.UTF8.GetString(decryptedData);
return new DecryptedRequest
{
DecryptedBody = decryptedJSONString,
AesKeyBuffer = decryptedAesKey,
InitialVectorBuffer = initialVectorBuffer
};
}
}
Расшифровка не удалась на следующем этапе:
using (var aesGcm = new AesGcm(decryptedAesKey))
{
decryptedData = new byte[encryptedFlowDataBody.Length];
aesGcm.Decrypt(initialVectorBuffer, encryptedFlowDataBody, decryptedData, encryptedFlowDataTag);
}
Сообщение об ошибке, которое я получаю:
System.ArgumentException: Указанный нонс не является допустимым размером для этого алгоритма. (Параметр ‘nonce’)
Эта ошибка предполагает, что initialVector
(нонс), передаваемый в расшифровку AES-GCM
, имеет недопустимый размер. Тем не менее, я подтвердил, что initialVector
правильно base64-декодируется
и передается, как ожидалось.
Кто-нибудь сталкивался с подобной проблемой при расшифровке AES-GCM
на C#? Какова может быть причина недопустимого размера нонса и как я могу ее решить?
Я пытался расшифровать это
{
"encrypted_flow_data": "33oaKOMa2tsRCuh7g6JNsFzVB5icbm4dLq3sgrRXImxChcGOKWaTEZycsv/Tgg/jB/7cxQWH9D8HvJFkCc78X/avxOtEj0KbF+TuFKG28xO/HMR3A4rpzSyD37UAJy3eSmQ5CHZV7NOOMteJQNAOZQ3YEpcG/BcH8mo2iOQa2EA/8g==",
"encrypted_aes_key": "NQBgEO5GMMXVHsRx0oDb+0MeTYPnHDZM2yJBG0CeaJ2VqN9ennPnLKknbVgpfRm7GfGSxsPHvO9sZeNs/SXlmYIoasDXw3pgKVjhPq3BOk93Fkfjs8bwBhDP763RCgO5IsOSgCqvNeGxeXxyM2BLr8rUAwoE74FYRLa6dxg5RGEUpGJjKLU8VZmBDbXanhPmy6+iVcLEE79rZLsA0+kU7IZ44eeR7PpvqiDCcrnjME/uCF24+3g+iVjsgcL5lA5DdhUQnfPnkjLTiC+x/NPp7ev3e7nP+PzTLQOxnnihjggRfYHUzklp9laVLAQoSQh7vvyKJUPyCv9BRhEmR7BJVQ==",
"initial_vector": "Vs37z73b5OiBJ5hMV0kyUQ=="
}
и это то, что я ожидаю хотя бы
Расшифрованный запрос:
{
"data": {
"farmer_select": "1"
},
"flow_token": "TEST",
"screen": "DEMO_SCREEN",
"action": "data_exchange",
"version": "3.0"
}
Ответ или решение
Решение проблемы дешифровки ответа сервера WhatsApp с использованием AES-GCM
Ошибка, с которой вы столкнулись, связана с неправильно заданным размером nonce (вектора инициализации) для алгоритма шифрования AES-GCM. Ваша реализация делает все правильные шаги, однако, возможные причины ошибки могут быть скорее всего связаны с неправильной длиной вектора инициализации.
Анализ проблемы
В соответствии со стандартами безопасности, AES-GCM требует, чтобы размер nonce составлял либо 12 байт (96 бит), либо 16 байт (128 бит). Однако, в вашем коде происходит base64 декодирование initial_vector
, и от этого может варьироваться его размер.
При этом, вы предоставили следующее значение для initial_vector
:
"initial_vector": "Vs37z73b5OiBJ5hMV0kyUQ=="
После декодирования base64, это значение будет представлять собой массив байтов. Для проверки правильности длины nonce, выполните следующий код:
byte[] initialVector = Convert.FromBase64String(body?.initial_vector);
if (initialVector.Length != 12) // либо 16
{
throw new ArgumentException("Размер nonce должен составлять 12 или 16 байт.");
}
Если длина initialVector
не равна 12 или 16, то это причина ошибки.
Решение проблемы
-
Проверка длины вектора инициализации: Убедитесь, что вектор инициализации соответствует требованиям алгоритма AES-GCM.
-
Корректировка значения вектора: Если ваш
initial_vector
короче 12 байт или длиннее 16 байт, вам нужно будет получить правильное значение вектора инициализации. Это может потребовать пересмотра логики формирования вектора инициализации на этапе шифрования. -
Проверка размера зашифрованного потока данных: Также обратите внимание на длину зашифрованного потока данных, который вы пытаетесь расшифровать. Убедитесь, что длина вашего
encrypted_flow_data
корректна и не была искажена.
Итоги
Проблема, с которой вы столкнулись при декодировании потока данных, скорее всего, возникает из-за несоответствия длины nonce. Проведите вышеуказанные проверки и внесите корректировки в ваш код.
Для дальнейшего устранения неполадок, рассмотрите возможность тестирования с различными фиксированными значениями для проверки механизма расшифровки. Используйте отладочные сообщения или логгирование для отслеживания промежуточных значений, чтобы получить более полное понимание происходящего на каждом этапе.
После исправления вышеупомянутых проблем, вы сможете успешно расшифровать данные WhatsApp flows.