在客户端存储数据 - 如何防止操纵?
Storing data on client side - How to protect against manipulation?
General/Introduction:
我在一个项目中工作,我们有两个软件部分。有一个在用户计算机上运行的客户端应用程序和一个管理与该项目相关的许多事情的 Web 应用程序。
客户端应用程序通过 IPC 从另一个程序中读取了很多不同的值,我没有它的源代码,而且我无法选择更改我正在读取的另一个程序中的任何内容。
因此,我的应用程序收集这些值并将它们存储在本地,因为它并不总是连接到 Web 应用程序。
由于 Web 应用程序从这些值中构建统计数据和更多信息,并且由于收集的值对整个项目非常重要,因此用户不应该能够更改它们(或者至少应该很难) - 我很确定您不能为客户端上的数据提供 100% 的安全性。
仅供参考:客户端应用程序是用 C# 编写的,而 Web 应用程序基于 Laravel 框架 (PHP)。但是这个问题更多的是关于理论,而不是具体如何编码。
我的想法:
我在考虑使用非对称加密。客户端使用 Web 应用程序服务器的 public 密钥对数据进行加密。数据现在以加密方式存储。但是当然,客户端有这个 public 键。因此,攻击者可以继续加密他自己的操纵值并将它们存储在文件中。
另一个基于加密的想法是,我不仅可以加密数据,还可以加密整个文件,并使用不太明显的格式。但这更像是通过默默无闻的安全,据我所知应该避免。另外一个可以反编译客户端应用程序并立即拥有我正在使用的格式。
我的问题:
将数据发送到服务器时,有什么方法可以提供良好的完整性?如果可以,怎么办?
您可以做两件事:
放弃,因为 client software authenticity is not the server's problem,理论上不可能确定另一端是 运行 你想要的软件,以一种不可欺骗的方式.
如果您将客户端软件用作数据骡子,请使用 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。
General/Introduction:
我在一个项目中工作,我们有两个软件部分。有一个在用户计算机上运行的客户端应用程序和一个管理与该项目相关的许多事情的 Web 应用程序。
客户端应用程序通过 IPC 从另一个程序中读取了很多不同的值,我没有它的源代码,而且我无法选择更改我正在读取的另一个程序中的任何内容。
因此,我的应用程序收集这些值并将它们存储在本地,因为它并不总是连接到 Web 应用程序。
由于 Web 应用程序从这些值中构建统计数据和更多信息,并且由于收集的值对整个项目非常重要,因此用户不应该能够更改它们(或者至少应该很难) - 我很确定您不能为客户端上的数据提供 100% 的安全性。
仅供参考:客户端应用程序是用 C# 编写的,而 Web 应用程序基于 Laravel 框架 (PHP)。但是这个问题更多的是关于理论,而不是具体如何编码。
我的想法:
我在考虑使用非对称加密。客户端使用 Web 应用程序服务器的 public 密钥对数据进行加密。数据现在以加密方式存储。但是当然,客户端有这个 public 键。因此,攻击者可以继续加密他自己的操纵值并将它们存储在文件中。
另一个基于加密的想法是,我不仅可以加密数据,还可以加密整个文件,并使用不太明显的格式。但这更像是通过默默无闻的安全,据我所知应该避免。另外一个可以反编译客户端应用程序并立即拥有我正在使用的格式。
我的问题:
将数据发送到服务器时,有什么方法可以提供良好的完整性?如果可以,怎么办?
您可以做两件事:
放弃,因为 client software authenticity is not the server's problem,理论上不可能确定另一端是 运行 你想要的软件,以一种不可欺骗的方式.
如果您将客户端软件用作数据骡子,请使用
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。