我有
attr_accessible :access_token
attr_encrypted :access_token, key: ENV['ENCRYPTION_KEY']
我正在做一些User.find_by_access_token
,所以我想索引数据库中的字段。
然而,不access_token
存在,只有encrypted_access_token
。
索引这个是否与索引任何其他字段相同?
我有
attr_accessible :access_token
attr_encrypted :access_token, key: ENV['ENCRYPTION_KEY']
我正在做一些User.find_by_access_token
,所以我想索引数据库中的字段。
然而,不access_token
存在,只有encrypted_access_token
。
索引这个是否与索引任何其他字段相同?
保存加密数据的全部目的是防止显示明文。显然你不能搜索它,否则整个概念就会有缺陷。
您可以使用普通索引对加密令牌进行索引,并使用加密令牌搜索表- 您显然需要加密密钥。
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>;
请注意,表达式必须与索引中的表达式匹配才能使索引有用。
但这会在多个层面上造成安全隐患。
我用谷歌搜索并找到了对加密字段快速搜索的参考。有评论提到“去识别数据”。似乎是一种公认的方法。
这是我设想它的工作方式。在此示例中,我将患者姓名与患者记录的其余部分分开。
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 自动执行此操作。
注意:仅控制对密码的访问本身就是一个棘手的问题。