我有一个使用 mysql 的 rails 3 应用程序。该应用程序将客户的电话号码和电子邮件存储在一个表格中。我想加密字段而不是将它们存储为普通和直接的值。这样,即使他/她可以访问数据库,该表对任何人都无用。
但是还有另一个问题。使用电子邮件和电话号码对记录进行大量查询,并进行索引。如何在不影响性能的情况下实现字段加密,并且仍然能够轻松搜索和匹配?
我有一个使用 mysql 的 rails 3 应用程序。该应用程序将客户的电话号码和电子邮件存储在一个表格中。我想加密字段而不是将它们存储为普通和直接的值。这样,即使他/她可以访问数据库,该表对任何人都无用。
但是还有另一个问题。使用电子邮件和电话号码对记录进行大量查询,并进行索引。如何在不影响性能的情况下实现字段加密,并且仍然能够轻松搜索和匹配?
首先,请记住,如果有人获得足够的访问权限来读取您的代码文件,他可能会获得您的解密例程和密钥——您的加密只会保护您免受访问数据库的攻击者的侵害,而不会其他任何东西。
如果您想使用 MySQL 搜索部分邮件地址和电话号码,则不能使用加密 - 如果数据以 MySQL 无法读取的方式加密,那么,MySQL 无法读取,因此无法搜索它。
但是,您可以执行以下操作:
如果要查找带有电子邮件 X 的行,请选择其中 email_hash = hash(X)。如果您想知道某一行的电子邮件地址,请选择 email_crypt 并对其进行解密。
但是,这将允许攻击者测试某个电子邮件是否在您的数据库中(即他们可以暴力破解哈希)。为了防止这种情况,您应该使用 HMAC 方法进行散列并保持密钥机密。
您现在可以想“嘿,我可以跳过哈希并通过加密纯电子邮件地址并查找包含相同加密字符串的行来进行查找”。不,你不能那样做。如果对数据进行加密,则使用与数据一起存储的随机“IV”,以确保如果对相同的数据进行两次加密,则会得到不同的结果。您可以将 IV 设置为一个常量值,但这是使用密码学的非标准方式,可能会导致安全问题,所以不要这样做。此外,请使用适当的链接模式,例如 AES-CBC。
它更容易在 MySQL 中完成。您可以使用简单的 MySQL 的ENCODE/DECODE函数或高级函数,如AES_DECRYPT()
或AES_ENCRYPT()
。
查看所有功能列表在这里。
注意:无论您使用什么,请确保将盐存储在该行的列中。并在您的应用程序配置文件中存储另一个盐。这将使用动态盐进行加密,您也可以保留部分盐的秘密。攻击者很难找回这些。