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

Bee*_*Dog 16 mysql encryption phpmyadmin

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

msg_id(主键,auto_increment)

user_id(指向创建消息的用户的外键)

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

msg(包含msg的VARCHAR)

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

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

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

rMX*_*rMX 21

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

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;
Run Code Online (Sandbox Code Playgroud)

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

UPDATE table SET msg = IF(accessable = 0, ENCRYPT(msg, 'key'), DECRYPT(msg, 'key'));
Run Code Online (Sandbox Code Playgroud)

所以你可以为你的PHP代码选择记录:

SELECT msg_id, user_id, time, IF(accessable = 0, DECRYPT(msg, 'key'), msg) msg
FROM table
Run Code Online (Sandbox Code Playgroud)

UPD.这里也有类似的问题:

MySQL加密列

  • 将钥匙放在触发器中是不是有点奇怪?如果有人访问数据库,他将能够看到密钥并解密数据...... (7认同)
  • 我同意@Roey 在触发器中传递密钥,这将使所有事情都无用。 (2认同)
  • 另外,如果您依赖触发器,如果​​数据库设置为记录查询,它将以纯文本形式捕获,从而使加密毫无用处(请参阅https://mariadb.com/kb/en/writing-logs-into-表/)。最好的选择是应用程序级加密,这就是 @Core Xii 在他的回答中广泛提到的内容。 (2认同)
  • ENCRYPT() 函数在 MySQL 5.7 中已弃用,在 MySQL 8.0 中被删除,不应再使用。对于单向哈希,请考虑使用 SHA2()。根据https://dev.mysql.com/doc/refman/5.7/en/encryption-functions.html#function_encrypt (2认同)

Cor*_*Xii 7

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