Общее / Введение:
Я работаю над проектом, в котором у нас есть две части программного обеспечения. Существует клиентское приложение, которое запускается на компьютере пользователя, и веб-приложение, которое управляет многими вещами, связанными с этим проектом.
Клиентское приложение считывает множество различных значений через IPC из другой программы, исходный код которой у меня отсутствует, и у меня нет возможности что-либо изменить в той другой программе, из которой я читаю.
Итак, мое приложение собирает эти значения и сохраняет их локально, поскольку оно не всегда связано с веб-приложением.
Поскольку веб-приложение строит статистику и многое другое из этих значений и поскольку собранные значения весьма важны для всего проекта, пользователь не должен иметь возможность их изменять (или, по крайней мере, это должно быть очень сложно — я уверен, что Вы не можете обеспечить 100% безопасность данных на клиенте).
Просто ради полной информации: клиентское приложение написано на C #, а веб-приложение основано на Laravel Framework (PHP). Но этот вопрос больше о теории, чем о том, как именно это кодировать.
Мои мысли:
Я думал о том, чтобы иметь асимметричное шифрование. Клиент шифрует данные с помощью открытого ключа сервера веб-приложений. Данные теперь хранятся в зашифрованном виде. Но, конечно же, у клиента есть этот открытый ключ. Следовательно, злоумышленник может просто зашифровать свои собственные манипулируемые значения и сохранить их в файле.
Другая мысль, основанная на шифровании, заключалась в том, что я мог не только зашифровать данные, но и весь файл и использовать формат, который не слишком очевиден. Но это больше похоже на безопасность через мрак, и, насколько я знаю, этого следует избегать. Плюс можно просто декомпилировать клиентское приложение и мгновенно получить формат, который я использую.
Мой вопрос:
Можно ли как-нибудь обеспечить достойный уровень целостности при отправке этих данных на сервер? Если так, как это можно сделать?
Вы можете сделать две вещи:
Сдавайся, потому что подлинность клиентского программного обеспечения не проблема сервера, и теоретически невозможно точно знать, что на другом конце выполняется программное обеспечение, которое вы намереваетесь таким образом, чтобы это не было подделкой.
Если вы используете клиентское программное обеспечение как мул данных, используйте hash_hmac()
а также hash_equals()
для проверки подлинности данных, чтобы они были подделаны.
Например, вы можете сохранить MAC, добавив его к данным:
$key = random_bytes(32); // Store me for long-term. Maybe per-client?
$data = "foo";
$mac = hash_hmac('sha256', $data, $key);
echo $data . $mac;
А затем, чтобы проверить его по возвращении клиентским программным обеспечением:
if (mb_strlen($message, '8bit') < 64) {
throw new Exception("Invalid message length.");
}
$mac = mb_substr($message, 0, 64, '8bit');
$data = mb_substr($message, 64, null, '8bit');
$recalc = hash_hmac('sha256', $data, $key);
if (!hash_equals($recalc, $mac)) {
throw new Exception("Invalid MAC.");
}
// Now we know $data is legitimate.
Важно использовать hash_equals()
не ==
или же ===
чтобы предотвратить время атаки.
Обратите внимание, что это делает любые такие данные неизбежно только для чтения. Если вы хотите, чтобы они могли редактировать данные, вы застряли с опцией 1.
Других решений пока нет …