如何加密MySQL表中的特定列?

时间:2010-11-25 10:12:05

标签: mysql encryption phpmyadmin

我正在尝试创建一个简单的消息系统(PHP)页面,该页面使用MySQL表来存储条目。我将在表格中使用的列的粗略轮廓是:

msg_id (主键,auto_increment)

user_id (指向创建邮件的用户的外键)

时间(提供msg时间戳的DATETIME条目)

msg (包含msg的VARCHAR)

可访问(只是一个int(1),0表示没有人除了用户自己可以读取msg,1表示其他人可以读取它)

我想知道的是,加密 msg 字段的最佳方法是什么,所以窥探眼睛无法读取它(比方说,打开mysql CLI或phpMyAdmin只读取值存储在一行)?

如果“accessable”设置为0,那么只有用户他/她自己应该能够读取它(通过访问某些PHP页面),但如果设置为1,其他人也应该能够读取它。我不知道如何解决这个问题,所以非常感谢任何帮助!

3 个答案:

答案 0 :(得分:20)

点击此处查看可能的加密功能列表:

http://dev.mysql.com/doc/refman/5.1/en/encryption-functions.html

您可以创建更新触发器并在那里检查字段accessable。这样的事情:

CREATE TRIGGER crypt_trg BEFORE UPDATE ON table FOR EACH ROW
BEGIN
  IF new.accessable = 0 THEN
    SET new.msg := ENCRYPT(new.msg, 'key');
  ELSE
    SET new.msg := DECRYPT(new.msg, 'key');
  END IF;
END;

您还可以使用此查询更新表中的所有现有记录:

UPDATE table SET msg = IF(accessable = 0, ENCRYPT(msg, 'key'), DECRYPT(msg, 'key'));

因此,您可以为您的PHP代码选择记录:

SELECT msg_id, user_id, time, IF(accessable = 0, DECRYPT(msg, 'key'), msg) msg
FROM table

UPD。此处也是类似的问题:

MySQL encrypted columns

答案 1 :(得分:6)

您还可以在查询之前对数据进行加密以插入数据,这样MySQL甚至不会知道它已加密,并在应用程序中检索时对其进行解密。为此,您应该将它存储在varbinary或blob列中。

答案 2 :(得分:-1)

所以我有一个想法可以实现这一目标,但这全是概念性的。

假设您的值是“ Lorem ipsum dolor sit amet”,而您想搜索“ lorem”。一种方法是,您可以将原件拆成小块(小写),然后放在第二张表中。整个(原始)值位于具有row_id 123的原始表列中,但是一个名为“ chunks”的新表可能具有:

row_id | chunk | foreign_row_id
1      | lo    | 123
2      | or    | 123
3      | re    | 123
4      | em    | 123
5      | m     | 123
6      |  i    | 123
7      | ip    | 123

把它想像成一个子字符串索引,其中每个子字符串长2个字符。

现在,当用户想要执行搜索时,您将类似地对其进行分块,然后进行查找。如果他们键入“ lo”,那么您会看到匹配的外部行ID。但是,如果他们输入“ lore”,那么您将搜索所有具有“ lo,“ or”和“ {{1}”匹配的块的外部行ID }”。

到目前为止,还不太实用。但是,如果原始值“ Lorem ipsum dolor sit amet”已加密或散列,则还可以对2个字符的子字符串进行分块,加密/散列,然后对块代替进行查找或完整的字符串。无需解密或散列。

逻辑将是:

  1. 对搜索字符串进行分块
  2. 加密/散列每个2个字符的块
  3. 进行查找并找到所有加密/散列的块匹配项。

然后可以从原始表中获取任何匹配项。这将保护静态数据,因为如果块表受到破坏,则它们对一堆加密/散列的2个字符的值将无能为力。您不能采用2个加密/散列的子字符串来重新组合它们或从中获取任何有意义的东西。

如果我是发明家并且要命名,因为它与制作Rainbow Table相似但不完全相同,因此我将其称为“ Fruity Pebbles Tables”。因为块。