防止 SQL 数据库中的数据欺诈和删除
Preventing Data Fraud and Deletion in SQL Database
我们有一个为许多客户本地安装的应用程序。我们正在尝试收集将在未来某个时间点发送给我们的信息。我们希望确保我们能够检测到我们的任何数据是否被修改以及是否有任何数据被删除。
为了防止数据被修改,我们目前对 table 行进行哈希处理,并将哈希值与数据一起发送。但是,我们正在努力检测数据是否已被删除。例如,如果我们在 table 中插入 10 条记录并散列每一行,用户将无法在我们检测不到的情况下修改记录,但如果他们删除所有记录,那么我们无法将其与初始安装区分开来。
约束条件:
- 客户将拥有数据库的管理员角色
- 应用程序和数据库将位于 DMZ 后面,无法连接外部服务
- 客户将能够分析任何 sql 命令,并能够复制我们所做的任何初始设置。 (为了澄清他们客户也可以 drop/recreate tables)
- 尽管客户端可以删除数据和 tables,但有一些数据集和 tables 如果删除或删除,我们在审核期间会很明显,因为它们应该始终在积累数据丢失的数据或截断的数据会很突出。我们希望能够在剩余的 table 中检测到删除和欺诈。
- 我们的工作假设客户将无法自行逆转我们的代码库或 hash/encrypt 数据
- 客户每月将收集的所有数据发送给我们,我们每年对系统进行一次审核。
- 还考虑到他们的客户端可以备份处于 'good' 状态的 DB 或 VM 的快照,然后在他们想要销毁数据时回滚到 'good' 状态。我们不想直接检测虚拟机快照或数据库备份回滚。
到目前为止,我们唯一的解决方案是加密安装日期(可以修改)和实例名称。然后每分钟'increment'加密数据。当我们向系统添加数据时,我们对数据行进行哈希处理并将哈希值粘贴到加密数据中。然后继续'increment'数据。然后,当发送每月数据时,我们将能够看到他们是否正在删除数据并将数据库回滚到刚安装后,因为加密值不会有任何增量,或者会有不属于的额外哈希值任何数据。
谢谢
假设我们在您的代码中有一个 md5() 或类似函数,并且您想控制 table "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";
每次授权更改 table "table1" 的信息后。没有人会在不被注意的情况下更改此系统。
如果有人更改了一些 id,您会注意到,因为散列将不一样。
如果有人想重新创建您的 table,除非他重新创建完全相同的信息,否则他将无法再次进行哈希,因为他不'知道了"secretkey-only-in-your-program"。
如果有人删除一条记录,它也可以被发现,因为"accumulatedIds" 不匹配。如果有人添加记录,这同样适用。
用户可以删除tablehash_control下的记录,但如果没有"secretkey...",他就无法正确重构哈希信息,所以你也会注意到这一点。
我错过了什么??
您是否调查过 Event Sourcing?如果性能足够好,这可能与一次写入介质一起用作辅助存储。这将保证交易的完整性,即使是针对 DB 或 OS 管理员。我不确定用真正的一次写入媒体做事件溯源是否可行,并且仍然保持合理的性能。
我们有一个为许多客户本地安装的应用程序。我们正在尝试收集将在未来某个时间点发送给我们的信息。我们希望确保我们能够检测到我们的任何数据是否被修改以及是否有任何数据被删除。
为了防止数据被修改,我们目前对 table 行进行哈希处理,并将哈希值与数据一起发送。但是,我们正在努力检测数据是否已被删除。例如,如果我们在 table 中插入 10 条记录并散列每一行,用户将无法在我们检测不到的情况下修改记录,但如果他们删除所有记录,那么我们无法将其与初始安装区分开来。
约束条件:
- 客户将拥有数据库的管理员角色
- 应用程序和数据库将位于 DMZ 后面,无法连接外部服务
- 客户将能够分析任何 sql 命令,并能够复制我们所做的任何初始设置。 (为了澄清他们客户也可以 drop/recreate tables)
- 尽管客户端可以删除数据和 tables,但有一些数据集和 tables 如果删除或删除,我们在审核期间会很明显,因为它们应该始终在积累数据丢失的数据或截断的数据会很突出。我们希望能够在剩余的 table 中检测到删除和欺诈。
- 我们的工作假设客户将无法自行逆转我们的代码库或 hash/encrypt 数据
- 客户每月将收集的所有数据发送给我们,我们每年对系统进行一次审核。
- 还考虑到他们的客户端可以备份处于 'good' 状态的 DB 或 VM 的快照,然后在他们想要销毁数据时回滚到 'good' 状态。我们不想直接检测虚拟机快照或数据库备份回滚。
到目前为止,我们唯一的解决方案是加密安装日期(可以修改)和实例名称。然后每分钟'increment'加密数据。当我们向系统添加数据时,我们对数据行进行哈希处理并将哈希值粘贴到加密数据中。然后继续'increment'数据。然后,当发送每月数据时,我们将能够看到他们是否正在删除数据并将数据库回滚到刚安装后,因为加密值不会有任何增量,或者会有不属于的额外哈希值任何数据。
谢谢
假设我们在您的代码中有一个 md5() 或类似函数,并且您想控制 table "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";
每次授权更改 table "table1" 的信息后。没有人会在不被注意的情况下更改此系统。
如果有人更改了一些 id,您会注意到,因为散列将不一样。
如果有人想重新创建您的 table,除非他重新创建完全相同的信息,否则他将无法再次进行哈希,因为他不'知道了"secretkey-only-in-your-program"。
如果有人删除一条记录,它也可以被发现,因为"accumulatedIds" 不匹配。如果有人添加记录,这同样适用。
用户可以删除tablehash_control下的记录,但如果没有"secretkey...",他就无法正确重构哈希信息,所以你也会注意到这一点。
我错过了什么??
您是否调查过 Event Sourcing?如果性能足够好,这可能与一次写入介质一起用作辅助存储。这将保证交易的完整性,即使是针对 DB 或 OS 管理员。我不确定用真正的一次写入媒体做事件溯源是否可行,并且仍然保持合理的性能。