确保传输数据的完整性

Ensure integrity of transmitted data

假设要在客户的计算机上部署一个软件应用程序(例如 IIS 网站)。出于许可和开具发票的目的,应用程序会定期将某些使用情况统计信息(例如托管实体的数量)发送回软件公司拥有的中央服务。确保传输数据完整性的最佳方法是什么(即,对客户系统具有管理权限的攻击者无法向中央服务发送虚假数据)?

显而易见的方法是在应用程序代码中对私钥进行硬编码以对数据进行签名,并混淆代码。只要密钥未被混淆,这将确保完整性。但是我们能比默默无闻的安全做得更好吗?

您无法确保数据的完整性。你能做的就是“尽力而为”的诚信。

鉴于评论中的额外信息:

The threat model is a cheating customer who can inspect but not modify the code, and who controls the communication channel to the central service

我们可以调查一下。

尽力而为

基本威胁是重播攻击:攻击者可以记录应用程序与中央服务之间的通信,例如Wireshark然后重新发送。
TLS 保护您免受这种情况的影响。

但是 TLS 的实现通常使用本机 OS 实现(例如 openssl),如果攻击者可以控制本机 OS 实现,他们可以轻松地进行设置可以解密和重放 TLS 流量。
添加请求 ID 和时间戳可以通过让服务器拒绝接受任何不是 e.g. 的内容来缓解这种情况。从最近 24 小时开始或使用在过去 24 小时内已经看到的请求 ID。

下一个威胁是攻击者发送带有新请求 ID 和时间戳的修改版本,以及可能使他们的作弊值得的其他修改字段。 你的下一道防线就是混淆有效负载。

根据兔子洞的深度,攻击者仍然可以使用 ltrace / gdb / jdb / visual studio, or by studying the bytecode / assembly code / CIL 代码等工具对其进行逆向工程。
那么,接下来要做的就是使用应用程序中嵌入的密钥对应用程序中的请求进行加密 and/or 签名。

但是如果攻击者拥有这台机器并且可以访问应用程序的文件,那么找到密钥并不难。
也许,您可以将密钥分解成许多无法识别的小部分,并将它们隐藏在应用程序的不同位置,并使用一些代码来重新 assemble 密钥。

但是如果攻击者看到它是signed/encrypted,他们就会去寻找密钥,当他们找不到时,他们会尝试从网络调用回溯到创建报告并查看应用程序如何获取密钥。

也许更好的选择是设置另一个分发密钥的服务:应用程序将请求一个密钥并使用它来加密中央服务的消息。

当然攻击者也可以调用这个服务。

另一种选择:现在有针对逆向工程设计的硬件,也许您的应用程序可能会在硬件不可用的情况下拒绝启动 - 取决于您的客户是谁。

我希望您看到这种最大努力如何使您的计费基础设施成为您的噩梦,而不是攻击者的噩梦。

常见的解决方案

通常公司在这种情况下所做的是在服务条款中加入使用报告和反逆向工程条款,尝试检测报告中的异常情况,当检测到异常时,进行调查并采取法律行动。

另一个你需要在架构层面问自己的问题:客户作弊的可能性有多大,在我检测到并将客户赶出之前,我总共要付出多少代价?
即:这个问题值得解决吗?