Мы разрабатываем приложение, которое должно работать с данными, зашифрованными LoraWan (https://www.lora-alliance.org)
Мы уже нашли документацию о том, как они шифруют свои данные, и читали ее последние несколько дней (https://www.lora-alliance.org/sites/default/files/2018-04/lorawantm_specification_-v1.1.pdf ), но в настоящее время все еще не может решить нашу проблему.
Мы должны использовать 128-битную расшифровку AES ECB с заполнением нулями для расшифровки сообщений, но проблема в том, что она не работает, потому что зашифрованные сообщения, которые мы получаем, недостаточно длинны для AES 128, поэтому алгоритм возвращает «Данные не являются полный блок» в последней строке.
Пример ключа, который мы получаем, выглядит следующим образом: D6740C0B8417FF1295D878B130784BC5 (ненастоящий ключ). Он имеет длину 32 символа, то есть 32 байта, но если рассматривать его как шестнадцатеричный, то он становится длиной 16 байтов, что необходимо для 128-битного AES. Это код, который мы используем для преобразования Hex из String:
public static string HextoString(string InputText)
{byte[] hex= Enumerable.Range(0, InputText.Length)
.Where(x => x % 2 == 0)
.Select(x => Convert.ToByte(InputText.Substring(x, 2), 16))
.ToArray();
return System.Text.Encoding.ASCII.GetString(hex);}
(Небольшая вещь, которую следует отметить для приведенного выше кода, заключается в том, что мы не уверены, какую кодировку использовать, поскольку мы не смогли найти ее в документации Lora, и они нам не сказали, но в зависимости от этой небольшой настройки мы могли испортить нашу расшифровка (хотя мы перепробовали все возможные комбинации, ascii, utf8, utf7 и т.д))
Пример сообщения, которое мы получаем: d3 73 4c, которое, как мы предполагаем, также в шестнадцатеричном формате. Это всего 6 байтов и 3 байта, если мы преобразуем его из шестнадцатеричного в обычный, по сравнению с 16 байтами, которые нам потребуются как минимум для соответствия длине ключа.
Это код для расшифровки Aes 128, который мы используем:
private static string Aes128Decrypt(string cipherText, string key){
string decrypted = null;
var cipherPlainTextBytes = HexStringToByteArray(cipherText);
//var cipherPlainTextBytes = ForcedZeroPadding(HexStringToByteArray(cipherText));
var keyBytes = HexStringToByteArray(key);
using (var aes = new AesCryptoServiceProvider())
{
aes.KeySize = 128;
aes.Key = keyBytes;
aes.Mode = CipherMode.ECB;
aes.Padding = PaddingMode.Zeros;
ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV);
using (MemoryStream ms = new MemoryStream(cipherPlainTextBytes, 0, cipherPlainTextBytes.Length))
{
using (CryptoStream cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read))
{
using (StreamReader sr = new StreamReader(cs))
{
decrypted = sr.ReadToEnd();
}
}
}
}
return decrypted;}
Таким образом, очевидно, что в sr.ReadToEnd() будет возвращено «Данные являются неполным блоком».
Как вы можете видеть из примера, в этой закомментированной строке мы также попытались «дополнить» текст до нужного размера полным нулевым массивом байтов правильной длины (16 — cipherText), и в этом случае алгоритм работает хорошо, но он возвращает полную тарабарщину, а не исходный текст.
Мы уже перепробовали все режимы работы и возились с режимами заполнения. Они не предоставляют нам ничего, кроме шифротекста и ключа для этого текста. Также нет вектора инициализации, поэтому мы предполагаем, что должны генерировать его каждый раз (но для ECB он даже не нужен iirc)
Более того, они могут отлично шифровать и расшифровывать свои сообщения. Что больше всего удивляет в этом, так это то, что я гуглю это уже несколько дней и не могу найти НИ ОДНОГО примера в Google, где ШИФРОТЕКСТ короче, чем ключ во время дешифрования.
Очевидно, я нашел примеры, когда сообщение, которое они Шифруют, короче, чем нужно, но это то, для чего заполнение на стороне ШИФРОВАНИЯ (правильно?). Таким образом, когда вы затем получите дополненное сообщение, вы можете сообщить алгоритму, какой режим заполнения использовался для придания ему правильной длины, чтобы затем он мог отделить дополнение от сообщения. Но во всех этих случаях полученное сообщение при расшифровке имеет правильную длину.
Так вот вопрос - что мы делаем не так? есть ли способ расшифровать зашифрованные тексты, которые короче ключа? Или они где-то ошибаются, создавая слишком короткие шифры?
Спасибо за любую помощь.