MySQL加密列

时间:2008-10-26 10:06:12

标签: mysql security encryption

假设表中的每一行都有与一个特定用户有关的数据。用户有密码可以访问系统。

如何使用InnoDB加密一列数据,以便除了数据用户以外的任何人都无法读取数据?我正在考虑使用一种MySQL加密函数(比如AES)和一个基于根据用户密码计算的哈希的密钥。

有没有人知道如何做到这一点?我是在正确的轨道上吗?

以下答案之一

  

修改用户密码的问题涉及通过新密码重新加密用户密钥,这比重新加密可以任意大的整个用户数据更直接。用户密钥在系统中的用户数据的整个生命周期内保持不变。

这有什么用?说密码是pass1。并且有一堆记录使用由此生成的密钥加密。如果用户现在将密码重置为pass2,我无法解密使用pass1加密的数据。如果用户完全忘记了密码,他的所有加密数据都将丢失。

7 个答案:

答案 0 :(得分:9)

我不知道使用用户的密码哈希加密数据是否有多大意义,如果您将哈希本身保留在数据库中,尤其是。在这种情况下,任何可以访问加密数据的人都可以访问密码哈希并解密数据。

另一种方法是使用特定于应用程序的密钥加密数据,并使用某些特定于用户的数据。但是,您面临另一个问题:如何安全地存储应用程序密钥。对于这个问题,我不知道一个简单的答案,但是如果您担心数据库数据可能受到损害,那么将其保留在源代码中可能已经足够了,但不是源代码本身,例如:如果您的数据库存储在异地(想想Amazon S3)。

如果您只在数据库中保留密码的哈希,那么使用用户密码保存应用密钥会有所帮助,但会引入另一个安全漏洞:您必须在应用会话中以明文形式保留用户密码。

至于技术解决方案,它很简单sample code is available。您可以按如下方式对其进行修改,以使用密码哈希加密的应用程序密码加密数据:

INSERT INTO secure_table VALUES (
  1,
  AES_ENCRYPT(
    'plain text data',
    CONCAT(@application_password, @user_password))
);

在任何情况下,您都必须将应用程序密码存储在某处,因此我认为没有一种简单的方法可以提供完美的安全性。

我能想到的另一种方法是向用户询问可以用作加密密钥的简短PIN。 PIN不会存储在数据库中,每次访问数据时都需要用户询问。

当然,您必须考虑加密的可行性。如果没有解密,您将无法索引或搜索它。可能需要一组有限的数据(例如信用卡号),但我不会对它有所了解。

答案 1 :(得分:2)

澄清问题中提到的答案之一:“user / app key”是随机生成的私钥,用于加密数据。私钥永远不会改变(除非它被泄露)。您使用密码加密和存储私钥。由于私钥比数据小得多,因此更改密码要便宜得多:您只需使用旧密码解密私钥并使用新密码对其进行重新加密。

答案 2 :(得分:1)

对于非用户特定(全局)的数据,您可以使用对称和非对称密码的组合。您可以拥有一个extra password字段,要求所有用户输入该字段,以便即使一个用户更改了一个密码,全局数据仍然可以用于具有不同密码的其他用户。

extra password可以与源代码中的另一个salt-like string按位xor'ed。它可以一起构成对称密钥来解密存储在数据库中的private key(永远不会改变)。使用private key解密extra password后,私钥可以解密并read数据库中的所有数据。私钥可以存储为会话变量。

顾名思义,public key可以作为纯文本字符串驻留在数据库中。当您需要write到db时,请使用公钥来加密数据。

您可以定期向用户提供新的extra password并重新加密静态private key,然后使用salt-like string进行xor'ing。

如果数据是用户特定数据而不是其他用户,则可以使用用户密码而不使用额外密码字段来加密私钥。管理员可以为特定用户提供另一份私钥副本,可以使用他的密码对其进行解密。

答案 3 :(得分:0)

我不认为这是最好的方法,除非您强制要求用户永远不能更改密码,或者每次用户更改密码时都有办法重新加密所有内容。

答案 4 :(得分:0)

您可以存储另一个密钥来加密/解密创建新用户时可能生成的用户特定数据。我们称这个新的密钥用户密钥。此用户密钥也应在数据库中加密,最直接的方法是通过用户密码或任何其他密码密码(如密码和创建/修改时间等)加密。

我会在用户会话中保留解密的用户密钥,以便在会话期间的任何所需时间访问用户的数据。

修改用户密码的问题涉及通过新密码重新加密用户密钥,这比重新加密可以任意大的整个用户数据更直接。用户密钥在系统中的用户数据的整个生命周期内保持不变。

当然,只有在登录时通过向服务器发送实际用户密码来执行身份验证时才能使用此方法,因为数据库只需要包含密码的哈希值。

答案 5 :(得分:0)

  

说密码是pass1。并且有一堆记录使用由此生成的密钥加密。如果用户现在将密码重置为pass2,我无法解密使用pass1加密的数据

密钥需要以可反转的方式加密,以便可以解密 使用pass1并使用pass2重新加密。

总结:

存储在数据库中的是:单向加密密码(用于密码检查), 其他数据的加密密钥,使用清除密码(或者无论如何,以与存储在数据库中的方式不同的方式加密的密码)进行可逆加密,以及使用clear加密密钥可逆加密的其他数据。

每当您需要其他数据时,您必须具有清除(或者与数据库中存储的加密方式不同的密码),读取加密密钥,使用密码对其进行解密,并使用该密码解密其他数据。

更改密码后,使用旧密码解密加密密钥,使用新密码加密并存储。

答案 6 :(得分:0)

如果您需要在没有用户交互的情况下访问数据(例如,对于数据库迁移),您将无法使用密钥进行解密。