2

我有

attr_accessible :access_token
attr_encrypted :access_token, key: ENV['ENCRYPTION_KEY']

我正在做一些User.find_by_access_token,所以我想索引数据库中的字段。

然而,不access_token存在,只有encrypted_access_token

索引这个是否与索引任何其他字段相同?

4

2 回答 2

2

保存加密数据的全部目的是防止显示明文。显然你不能搜索它,否则整个概念就会有缺陷。

您可以使用普通索引对加密令牌进行索引,并使用加密令牌搜索表- 您显然需要加密密钥。

CREATE INDEX tbl_encrypted_access_token_idx ON tbl(encrypted_access_token);

SELECT *
FROM   tbl
WHERE  encrypted_access_token = <encrypted_token>;

如果IMMUTABLE您的所有令牌都可以使用Postgres 函数解密,您可以在表达式上使用索引

CREATE INDEX tbl_decrypted_token_idx
ON tbl(decrypt_func(encrypted_access_token));

SELECT *
FROM   tbl
WHERE  decrypt_func(encrypted_access_token) = <access_token>;

请注意,表达式必须与索引中的表达式匹配才能使索引有用。

但这会在多个层面上造成安全隐患

于 2012-08-09T00:03:44.490 回答
0

我用谷歌搜索并找到了对加密字段快速搜索的参考。有评论提到“去识别数据”。似乎是一种公认​​的方法

这是我设想它的工作方式。在此示例中,我将患者姓名与患者记录的其余部分分开。

Patient Row: [id=1, name_and_link=9843565346598789, …] Patient_name Row: [id=1, name=”John”, patient_link=786345786375657]

name_and_link 字段是两个字段的加密副本:名称和指向 Patient_name 的链接。在两个表中都有名称是多余的。我建议它提供更快的访问(无需从 Patient_name 表中读取)。如有必要,还允许重新创建 Patient_name 表(例如,如果两个表不同步)。

Patient_name 表包含名称值的未加密副本。名称行可以被索引以便快速访问。要按名称搜索,请在 Patient_name 表中找到匹配的名称,然后使用加密链接返回 Patient 表。

注意:在上面的示例中,我将长数字显示为示例加密数据。实际上,在现实生活中情况更糟。根据加密方法,使用 Postgres 的 pgp_sym_encrypt() 函数的加密值的最小长度约为 67 字节。这意味着将字母“x”加密为 67 个字节。我建议为每个去标识字段设置两个加密字段。这就是为什么我建议在 Patient 表中将名称和链接一起加密(作为 JSON 元组?)。与分别加密两个字段相比,将空间开销减少了一半。

注意:这需要将一些字段分成几部分。(例如电话号码、SSN、地址)。每个部分都需要存储在单独的表中。即使是地址的街道部分也必须进一步细分。这变得越来越复杂。我希望看到 Postgres 自动执行此操作。

注意:仅控制对密码的访问本身就是一个棘手的问题。

于 2015-08-21T13:51:38.103 回答