1

如果我有一行数据,例如:

1, 2, 3

我可以创建一个校验和值,它是所有列的总和,1 + 2 + 3 = 6。我们可以将此值与第 4 列中的行一起存储:

1, 2, 3, 6

然后我可以编写一个程序来检查列中的任何值是否意外更改,如果列的总和与校验和值不匹配。

现在,我想更进一步。假设我有一个值表,任何人都可以读/写访问,其中最后一列数据是前面所述的前列的总和。

1, 2, 3, 6

假设有人想偷偷摸摸并更改第三列中的值

1, 2, 9, 6

校验和很容易重现,所以鬼鬼祟祟的人只需将校验和值更改为 1 + 2 + 9 = 12,这样该行就不会被篡改。

1, 2, 9, 12

现在我的问题是,我怎样才能制作一个更复杂的校验和值,这样一个鬼鬼祟祟的人就无法在不使校验和不再有效的情况下进行这种类型的更改?也许我可以创建一个黑盒 exe,给定行的前三个值可以给出一个更复杂的校验和,例如:

a^2 + b^2 + c^2

但是,虽然这个逻辑对于狡猾的用户来说是未知的,但他/她仍然可以将这些值输入到黑盒 exe 中并得到一个有效的校验和。

关于如何确保表中的所有行都未被篡改的任何想法?我试图避免的方法是每次使用我正在创建的程序对其进行合法修改时保存表的副本。这是可能的,但似乎是一个非常不雅的解决方案。必须有更好的方法,对吧?

4

4 回答 4

1

使用基本数学你的校验和是无效的:

a^2 +b^2 +c^2  

a=0,b=0,c=2  = checksum 4
a=2,b=0,c=0  = checksum 4

如果您想为用户提供一组“只读”数据,请考虑使用物化视图。物化视图将提前计算计算,即您的有效数据并将其提供给用户,而您的程序可以在后台进行修改。

此外,这就是特权存在的原因,如果您仅提供无法修改数据库的帐户(例如只读访问),则可以减轻有人篡改数据的问题。此外,您不能完全阻止恶意用户篡改数据,只能让他们跳过几个圈,希望他们暂时感到无聊/被阻止。

安全没有灵丹妙药,您可以做的是使用包含以下功能的深度防御思维:

广泛的日志记录、
职责划分、
工作轮换、
补丁管理、
日志审计(与日志记录一起使用,但实际上必须有人阅读它们)、
实施 HIPS 系统(主机入侵防御系统)、
拒绝与数据库的外部连接

该列表可以相当广泛。

于 2013-01-10T20:10:04.117 回答
1

您似乎在问,“我怎样才能给一个程序一组不同的安全权限给运行它的用户?” 这样做的方法是确保程序在与用户不同的安全上下文中运行。执行此操作的方法因平台而异。

如果您有多台机器,那么运行客户端服务器架构会有所帮助。您通过服务器公开受控 API,它具有数据库的安全凭证。那么您的用户就不能提出任意请求。

如果您是客户端计算机的管理员,而用户不是,那么您可以让单独的进程执行类似的操作。例如,unix 中的守护进程。我认为 Windows 中的 DCOM 可以让你做这样的事情。

另一种方法是通过存储过程公开您的 API,并且只授予对这些的访问权限,而不是直接访问表。

控制对有限 API 的访问可能还不够。例如,考虑一个存储游戏中高分的表格。ClaimHighScore如果用户可以输入任意值,则只能通过 API 访问它并不重要。游戏中的解决方案通常很复杂。我听说的唯一可行的方法是根据给出初始游戏状态的种子值定义 API,然后是一组带有时间戳的输入。然后服务器必须基本上模拟游戏来验证分数。

于 2013-01-10T20:44:52.070 回答
1

用户不应拥有对表的无限制写访问权限。更好的是为常见的 CRUD 操作创建存储过程。这将让您控制他们可以修改哪些字段,并且如果您坚持可以更新CRC()校验和或其他验证。

这将是一个大项目,所以现在可能不实用 - 但这是应该做的事情。

于 2013-01-10T22:20:15.687 回答
0

尽管您的问题是基于对数据库的恶意条目,但使用MOD11可以找到不准确或放错位置的值。

以下 MySQL 语句和SQLfiddle说明了这一点

SELECT id, col1, col2, col3, col4, checknum,
9 - MOD(((col1*5)+(col2*4)+(col3*3)+(col4*2) ),9) 
AS Test FROM  `modtest` HAVING checknum =Test
于 2013-01-10T22:53:00.177 回答