我们有一个为许多客户端安装在本地的应用程序。我们正在努力收集将在未来某个时候发送给我们的信息。我们要确保我们可以检测到是否有任何数据被修改或删除。
为了防止数据被修改,我们当前哈希表行并发送哈希数据。然而,我们正在努力检测数据是否已被删除。例如,如果我们在一个表中插入10条记录,并对每一行进行散列,用户将无法在我们检测到的情况下修改记录,但如果他们删除了所有记录,那么我们就无法将其与初始安装区分开来。
约束条件包括:- 客户端将拥有数据库的管理员角色
- 应用程序和数据库将在DMZ后面,无法连接外部服务
- 客户端将能够配置任何sql命令,并能够复制我们所做的任何初始设置。(为了澄清客户端也可以删除/重建表)
- 虽然客户端可以删除数据和表,但有一些数据和表集如果在审计期间被删除或删除对我们来说是显而易见的,因为它们应该总是在积累数据,丢失的数据或截断的数据将会突出。我们希望能够在剩余的表中检测到删除和欺诈。
- 我们正在假设客户端将无法逆转我们的代码库或哈希/加密数据
- 客户每月将收集到的所有数据发送给我们,我们每年将对系统进行一次审核。
- 还考虑到他们的客户端可以在"良好"状态下备份DB或VM的快照,然后如果他们想要销毁数据,则可以回滚到该"良好"状态。我们不想直接检测vm快照或db备份回滚。
谢谢
您看过Event Sourcing吗?如果性能足够好,这可能会与write-once介质一起用作辅助存储。这样就可以保证事务的完整性,即使对数据库或操作系统管理员也是如此。我不确定是否可行做事件溯源与真正的写一次媒体,仍然保持一个合理的性能。
假设我们在代码中有一个md5()或类似的函数,并且您希望保持对表"table1"的"id"字段修改的控制。你可以这样做:
accumulatedIds = "secretkey-only-in-your-program";
for every record "record" in the table "table1"
accumulatedIds = accumulatedIds + "." + record.id;
update hash_control set hash = md5(accumulatedIds) where table = "table1";
每次授权修改表"table1"的信息后。没有人可以在不被发现的情况下修改这个系统。
如果有人改变了一些id,你会注意到,因为哈希值不一样了。
如果有人想重新创建你的表,除非他重新创建完全相同的信息,否则他将无法再次生成哈希,因为他不知道"secret -only-in-your-program"。
如果有人删除了一条记录,它也可以被发现,因为"accumulatedIds"不会匹配。如果有人添加了一条记录,也同样适用。
用户可以删除hash_control表下的记录,但是如果没有"secretkey…",他就不能正确地重建哈希信息,所以您也会注意到这一点。
我错过了什么??