问题
我试图在接下来的几段中解释完整的场景。我认为这对于获得一些提出问题的背景很重要,所以请耐心等待,即使它是一堵文字墙。
我目前的任务是以安全的方式匿名数据。这个想法是用来HMAC(<string to anonymize>, key)匿名化数据,这样它就不能被逆转。例如,如果您有一个客户 ID ( CUST299128218),这将是 HMAC-ed,SECRET用作543a36dd07fe4a3fa4a2db202546eaaccaef71f871ebafe11de3b54784ba266e. 由于我们想要对匿名数据进行分析,因此相同的客户 ID 始终会产生相同的 HMAC 摘要是很重要的。所以我们不能丢弃密钥,因为我们需要用相同的密钥对未来的数据进行匿名化。
显然,钥匙需要存放在安全的地方,这样它就不会泄露出去。否则,知道客户 ID 的人可以轻松地在匿名数据中找到该特定客户。由于各种技术/组织原因,我们不能使用硬件安全模块来存储密钥。所以我看了一下 HashiCorp 的 Vault,它似乎很适合这个,因为它提供了一个REST API,你可以在其中给它一个明文,并使用以前存储的密钥返回这个明文的 HMAC。密钥永远不会离开 Vault,这比将密钥存储在匿名软件的某些配置属性中要好得多。
然而,我们谈论的是要匿名的大量数据集 (每天几十万到几百万),并且可以预见为每个数据集调用 Vault API(如果需要对多个项目进行匿名化,可能会多次调用)将导致大量开销,可能会使我们为此可用的基础设施不堪重负。
建议的解决方案
因此我有了这个想法:如果我使用一些固定的字符串(例如'customer_id_secret_bootstrap')并让 Vault 使用密钥在其上创建一个 HMAC 会怎样。然后我使用这个 HMAC 作为对数据进行匿名化的实际 HMAC 的密钥。在功能方面:
temp_key = CALL_VAULT('customer_id_secret_bootstrap')
anonymized_text = HMAC( <plaintext>, temp_key)
这样我只能调用一次 Vault 并将临时密钥保存在内存中。我应该始终从 Vault 中取回相同的临时密钥(因为它是 HMAC),但原始密钥(用于派生临时密钥)永远不会离开 Vault,并且当程序退出时,无法重新创建临时密钥无需访问 Vault。因此,通过这种方式,我可以确保密钥的安全性,同时不会对 Vault 进行一百万次调用。
问题
现在知道我到目前为止还不是安全专家,由于我不知道的原因,这可能是一个糟糕的主意。因此,我想在这里与您的专家一起运行此程序-您能告诉我这是一个好主意还是坏主意,如果这是一个坏主意,您能否提出一些替代方法来确保密钥的安全性并具有可扩展性?
更新/编辑
正如许多答案指出的那样,仅仅替换 ID 是不够的,因为还有其他字段可用于将信息关联到一小组人甚至一个人(例如时间戳非常适合此)。我们还通过删除或替换此类信息来解决此问题,以确保不会发生这种情况(我们有一个非常长的基于匿名标准的关于此类事情的清单)。我只是不想在这里介绍这些细节,因为这个问题已经很冗长了。