我正在开发一个使用pkg_crypto来保护用户个人信息的项目。有几千行(预计会增长到几万行),每当我在查询中使用WHERE
或ORDER BY
子句时,整个表在结果返回之前被解密。对于单个查询,这需要几秒钟,这可用于开发,但对于发布可能不太好。
有没有办法创建一个可以在不影响安全性的情况下处理加密列的索引?
插入和选择看起来像这样(使用iBatis):
插入
INSERT INTO "USER_TABLE"
(
"ID"
,"LOGIN"
,"PASSWORD"
,"NAME"
,"EMAIL"
)
VALUES
(
user_table_seq.nextval,
#login#
,#password#
,pkg_crypto.encrypt(#name#, 'key')
,pkg_crypto.encrypt(#email#, 'key')
)
选择
SELECT
"ID"
,"LOGIN"
,"PASSWORD"
,pkg_crypto.decrypt("NAME", 'key') NAME
,pkg_crypto.decrypt("EMAIL", 'key') EMAIL
FROM "USER_TABLE"
WHERE pkg_crypto.decrypt("NAME", 'key') LIKE #name# || '%'
AND pkg_crypto.decrypt("EMAIL", 'key') LIKE '%' || #email#
我会抢先说出密码在传递给db之前由servlet进行了哈希处理。
答案 0 :(得分:4)
您是否需要使用PKG_CRYPTO
来加密数据(我认为,这是您编写的调用DBMS_CRYPTO
或DBMS_OBFUSCATION_TOOLKIT
的内容?Oracle具有名为{的功能{3}}(尽管这是一个额外的成本选项),允许您让Oracle透明地加密磁盘上的数据,在从磁盘读取数据时对其进行解密,然后对数据使用这种LIKE
谓词
答案 1 :(得分:3)
基本上,答案是否。
当每个值都被加密时,它会选择随机的IV(初始化向量)。这意味着您无法预测索引的内容。如果重新加密该值(即使使用相同的密钥),您将得到不同的结果。因此,您无法在加密值上有意义地使用索引,因为您无法为要搜索的值重现加密。无论如何,该索引仅对平等搜索有用。数据将按随机顺序排列。
使用存储的哈希值(以及加密值)可能会做得更好。如果使用已知算法散列名称,则可以根据需要重现散列值并查找匹配的行。但只是知道哈希不允许你(或入侵者)确定被散列的值,除非通过预先计算的'彩虹表'。
因此,您无法对加密列进行有意义的索引 - 即使是唯一性也是如此(因为相同的值会因随机IV而以不同的方式加密)。