我有
attr_accessible :access_token
attr_encrypted :access_token, key: ENV['ENCRYPTION_KEY']
我正在做一些User.find_by_access_token
,所以我想索引数据库中的字段。
但是,不存在access_token
,只有encrypted_access_token
。
对此进行索引是否与索引任何其他字段的内容相同?
答案 0 :(得分:2)
保存加密数据的重点是防止明文显示。显然你不能搜索它,否则整个概念就会有缺陷。
您可以使用普通索引为加密标记编制索引,并使用加密标记搜索该表 - 您显然需要加密密钥。
CREATE INDEX tbl_encrypted_access_token_idx ON tbl(encrypted_access_token);
SELECT *
FROM tbl
WHERE encrypted_access_token = <encrypted_token>;
如果所有令牌都可以使用IMMUTABLE
Postgres功能解密,则可以使用index on an expression:
CREATE INDEX tbl_decrypted_token_idx
ON tbl(decrypt_func(encrypted_access_token));
SELECT *
FROM tbl
WHERE decrypt_func(encrypted_access_token) = <access_token>;
请注意,表达式必须匹配索引中索引的表达式才有用。
但这会在多个级别上造成安全隐患。
答案 1 :(得分:0)
我用Google搜索并找到Fast Search on Encrypted Field的引用。评论提到“取消识别数据”。似乎是accepted method。
以下是我设想的工作方式。在本例中,我将患者姓名与患者记录的其余部分分开。
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个字节。我正在为每个de-id'd字段提出两个加密字段。这就是为什么我建议在Patient表中加密名称和链接(作为JSON元组?)。将空间开销减半,而不是分别加密两个字段。
注意:这需要将一些字段分成几部分。 (例如电话号码,SSN,地址)。每个部分都需要存储在一个单独的表中。甚至地址的街道部分也必须进一步细分。这变得复杂了。我想看看Postgres自动化这个。
注意:仅控制对密码的访问本身就是一个棘手的问题。