如何在数据传输流程中对个人身份信息进行加密,同时确保这些信息仍可被检索到
在Intuit,我的团队构建了一个数据处理流程,用于处理TurboTax电子申报系统中产生的数据。这些数据需要被用于制作仪表板、进行分析,以及满足其他后续使用需求。 其中最大的挑战之一就是如何保护那些属于 个人身份信息 的数据,比如社会安全号码。这类信息具有极高的敏感性,因此在数据处理的每一个环节都必须得到妥善保护。与此同时,分析团队有时也需要进行一些正常的业务操作,例如识别与特定客户相关的记录,或者进行精确匹配查询。 那么,如何在保证这些敏感信息不被泄露的同时,允许人们对这些数据进行受控的搜索呢?在本文中,我将解释解决这一问题所涉及的加密技术原理,包括以下内容: 概率加密与确定性加密 对加密
概率加密与确定性加密
对加密数据的搜索操作
基础密钥与派生密钥
密钥分离机制
本地加密操作与远程加密操作
数据标记化技术
使加密数据可被搜索所涉及的安全权衡
目录
为何要加密个人身份信息?
像社会安全号码、电子邮件地址、电话号码以及财务信息这类个人身份信息,都具有极高的敏感性。如果你直接将这些信息的明文形式存储在数据仓库或数据库中,那么存储层一旦发生安全漏洞,就会导致大量敏感信息被泄露。加密通过将明文转换为密文来提供保护:
明文
│
▼
加密 + 密钥
│
▼
密文
社会安全号码:111-22-3333
加密后的结果:8f92a7c1...
如果没有适当的加密密钥,密文就无法揭示原始明文的内容。
然而,对于数据平台而言,加密还会带来其他要求。
社会安全号码 = 111-22-3333
如果该社会安全号码已经被加密,我们就不希望该应用程序为了进行简单的匹配查询而解密整个数据集。
AES:高级加密标准
AES(高级加密标准)是一种被广泛使用的对称加密算法,用于保护敏感数据。它使用密钥将明文转换为密文,而同样的密钥也被用来解密密文,使其恢复为原始的明文。
明文:111-22-3333
密钥:key1
↓ AES加密
密文:8f92a7c1...
AES被广泛用于保护诸如个人身份信息这类敏感数据。但是,加密的具体效果取决于其实现方式和使用方法。其中一个重要的因素就是加密过程中是否使用了随机性。
概率加密
Encrypt("ABC", key1) → qwoeoewowe
Encrypt("ABC", key1) → cXcslslsd
Encrypt("ABC", key1) → fjkdfdfd
尽管输入内容完全相同:
ABC
加密后的结果却各不相同。
这种随机性是刻意设计的。这样,别人在查看加密数据时,就无法轻易判断出两个加密文本是否代表相同的原始信息。
举个例子:
记录1 → qwoeoewowe
记录2 → cXcslslsd
记录3 → fjkdfdfd
观察者无法仅通过比较加密文本就判断这些记录是否包含相同的明文内容。
因此,当保密性是首要需求时,概率加密是一种非常合适的选择。
优势
能有效防止基于模式分析的破解尝试
使重复出现的明文在加密后呈现出不同的结果
适用于那些不需要直接比较加密后的数据的情况
局限性
虽然这种随机性增强了安全性,但同时也给数据分析带来了困难。
假设我们想要查找所有包含以下信息的记录:
SSN = 111-22-3333
如果同一个SSN被多次加密,那么它的加密结果可能会是:
111-22-3333 → X8a91...
111-22-3333 → P72k4...
111-22-3333 → M91q2...
尽管这些加密结果的原始SSN是相同的,但它们本身却不同。
因此,像这样的简单查询:
WHERE encrypted_ssn = encrypted_search_value
是无法可靠地执行匹配操作的。
这对数据平台来说是一个重要的权衡:随机性确实能更好地防止信息泄露,但也会使基于匹配条件的搜索变得更加困难。
当数据分析需要对敏感字段进行精确匹配时,我们就需要另一种加密方法:确定性加密。
确定性加密
确定性加密的设计原则是:使用相同的密钥和加密规则对相同的明文进行加密时,一定会得到相同的加密结果。
Encrypt("ABC", key) → adsfffdfd
Encrypt("ABC", key) → adsfffdfd
Encrypt("ABC", key) → adsfffdfd
其核心特点就是:
SELECT *
FROM customer_data
WHERE encrypted_ssn = EncryptDeterministically('111-22-3333', encryption_key);
应用程序可以为搜索值生成相同的加密结果,然后与存储在数据库中的加密结果进行比对。
安全性与便利性的权衡
确定性加密虽然能够实现数据的可查询性,但这种可查询性是需要付出代价的。
以这个数据集为例:
密文
-----------
A9F82...
A9F82...
B72AC...
A9F82...
C81DE...
攻击者可能并不知道:
A9F82... = 111-22-3333
但他们可以确定,相同的明文出现了三次。
换句话说,确定性加密会暴露出数据之间的对应关系。
如果攻击者掌握了关于该数据集的额外信息,他们就可以利用这些规律来推断出明文的值。
对于那些可能取值范围较小的字段来说,这一点尤为重要,例如:
州代码
布尔值
性别分类
小型分类字段
其他低熵属性
因此,只有在确实需要实现数据查询功能,且这种需求值得为此承受额外的安全风险时,才应使用确定性加密。
基础密钥与派生密钥
安全的加密架构中另一个关键部分就是密钥管理。
一种常见的设计方法是使用一条受到严格保护的根密钥或主密钥,然后为特定的用途生成不同的派生密钥,而不是在所有地方都使用同一把密钥。
下图说明了密钥分离的原则:对于不同类型的数据,不应使用相同的密钥;而是可以利用受保护的主密钥作为密钥体系的根基,从而为不同的数据集、加密需求或环境生成专门的派生密钥。
例如,某个数据集可以使用特定的密钥进行加密,而用于加密社会安全号码的密钥则应单独设计。这样就能限制每把密钥的使用范围,降低其中一把密钥被泄露所带来的风险。
密钥分离的核心思想就是:不同的加密用途应该使用不同的密钥或加密机制。
一个组织可能会为以下场景生成不同的密钥:
生产数据 + 个人身份信息 + 社会安全号码的加密
以及另一组用于:
生产数据 + 个人身份信息 + 电子邮件的加密
具体的密钥层次结构需要根据应用程序的安全需求来确定。
使用HKDF进行密钥生成
用于生成加密密钥的一种常见标准是HKDF,也就是基于HMAC的密钥生成函数。
HKDF(基于HMAC的密钥派生函数):这是一种从单一主密钥中派生出多个密钥的标准方法。
下图展示了HKDF如何从同一个主秘钥中派生出不同的密钥。HKDF以该主秘钥作为输入,同时还会结合用于说明具体用途的上下文信息。例如,当上下文为“SSN加密”时,会生成一个派生密钥;而当上下文为“电子邮件加密”时,则会生成另一个派生密钥。
由于上下文信息不同,即使这些密钥都源自同一个主秘钥,它们在加密层面上也是相互独立的。这种机制也可以用于其他场景,比如令牌生成。
关键在于,应用程序并不需要为每种用途都维护一个完全独立的主秘钥。实际上,可以使用一个经过安全管理的根密钥作为派生特定用途密钥的起点。
因此,上下文信息在密钥派生机制中起着至关重要的作用。
举个例子:
DerivedKey =
HKDF(
master_secret,
context = "production:ssn"
)
如果使用不同的上下文信息,就会生成不同的派生密钥:
DerivedKey =
HKDF(
master_secret,
context = "production:email"
)
这种设计能够有效实现密钥的隔离。
如果某个派生密钥被泄露,使用该密钥保护的数据并不会因此自动暴露风险。
然而,仅仅通过密钥派生机制本身,并不能确保被泄露的加密数据就绝对安全了。如果某个派生密钥被破解,那么所有使用该密钥保护的数据仍然可能面临危险。
主密钥应该存储在哪里?
根密钥不应该被保存在应用程序的源代码或配置文件中。
通常,组织会使用专门的密钥管理系统或硬件安全模块来存储主密钥。
硬件安全模块:这是一种用于安全存储数字密钥并执行加密操作的物理设备或云服务。
常见的硬件安全模块包括:
AWS Key Management Service (KMS)
Google Cloud KMS
Azure Key Vault
专用的硬件安全模块基础设施
密钥管理系统能够提供受控的访问权限、审计功能、密钥轮换机制,并且还能与身份认证和访问控制系统集成。
应用程序应该只获取它真正需要的加密材料或加密操作相关功能。
本地加密操作
在本地加密工作流程中,应用程序负责实际的数据加密工作。
在这种工作流程中,KMS负责保护根密钥或数据加密密钥,而应用程序则在本地执行实际的加密操作。应用程序首先会向KMS请求数据加密密钥,KMS会返回该数据密钥及其受保护的副本。这样,应用程序就可以使用这个数据密钥来对数据进行加密,而无需为每一个具体的数据值都向KMS发起请求。
对于处理大量数据的场景来说,这种方案更具可扩展性,因为应用程序可以在本地对大量数据进行加密,而KMS则负责保护更高层级的密钥。数据加密密钥应被视为敏感信息,因此只应在必要时才将其保存在应用程序的内存中。
应用程序会使用适当的数据加密密钥或派生的加密密钥来执行加密操作。
优势
高吞吐量
对于大型数据集而言,所需的网络请求次数较少
适用于批量处理和数据管道场景
单个加密操作的延迟较低
需要注意的事项
应用程序所使用的加密密钥会暂时保存在应用程序的内存中。
因此,应用程序的安全性成为整个密钥保护策略的重要组成部分。
远程加密操作
在远程加密工作流程中,应用程序会将加密请求发送给KMS,而不是自己执行加密操作。KMS会使用受保护的密钥来完成加密工作,并将生成的密文返回给应用程序。而底层的加密密钥本身仍然保存在KMS的内部。
这种方式能够实现对加密操作的集中控制和审计,但每次加密请求都会引发一次网络交互。对于处理大量数据的情况来说,这种机制可能会导致延迟增加,因此可能不太适合用于大规模地加密单个数据值。

该应用程序并未接收底层密钥资料。这样一来,就可以减少密钥的直接暴露风险,并实现加密操作及审计工作的集中管理。
优势
密钥访问管理更加集中
密钥可以始终处于受管理的加密环境中
授权与审计工作得以集中处理
对于那些适合使用远程加密API的场景而言,这种方案非常实用
弊端
网络延迟问题
API的处理能力存在限制
需要依赖其他额外的运营机制
当需要进行大量加密操作时,可能会产生额外的成本
对于处理海量数据的流程而言,为每一列或每一行数据都调用远程KMS服务可能是不切实际的。
确定性加密与HMAC的对比
当唯一的需求仅仅是进行匹配验证时,另一种方案也值得考虑。
假设分析团队并不需要从存储的数据中恢复原始的社保号码信息,他们只需要回答以下问题:
“这条记录中的社保号码与搜索结果中的社保号码是否相同?”
在这种情况下,使用可逆加密可能并无必要;而像HMAC这样的基于密钥的加密哈希值反而可能是更合适的选择。
HMAC(秘钥, 标准化社保号码)
例如:
111-22-3333
│
▼
HMAC(秘钥, 社保号码)
│
▼
X7a91f...
相同的社保号码会生成相同的HMAC值:
111-22-3333 → X7a91f...
111-22-3333 → X7a91f...
222-33-4444 → P3k21...
这样就可以进行匹配验证了:
WHERE ssn_hmac = HMAC(秘钥, '111-22-3333')
但与加密不同,HMAC并不具备可逆性。当分析数据集中不需要恢复原始信息时,这种特性反而是一种有益的安全措施。
在决定是否使用确定性加密还是HMAC时,需要综合考虑各种需求、威胁模型、密钥管理机制,以及是否需要可逆性等功能。
令牌化技术
另一种常见的方法是令牌化。
instead of storing the original value directly, the system stores a token instead.
例如,原本存储的社保号码“111-22-3333”会被替换为类似“TOKEN-8F72A1”的令牌。
111-22-3333
→ TOKEN-8F72A1
原始值与令牌之间的对应关系由安全的令牌化服务或存储系统来维护。
数据处理流程及分析系统可以直接使用这些令牌,而无需处理原始的个人信息。
下图展示了如何通过令牌化技术将敏感信息与数据处理系统分离:原始的社保号码会被发送到安全的令牌存储系统中,该系统会生成相应的令牌;这个存储系统会确保原始社保号码与其对应的令牌之间的安全性。
数据湖中存储的仅是令牌,而非原始的社会安全号码。下游系统可以使用该令牌作为标识符来匹配或关联记录,而无需直接存储这些敏感信息。如果某个授权系统确实需要原始的社会安全号码,它可以在适当的访问控制机制下,通过与令牌管理系统进行交互来获取该令牌。
当许多下游系统需要使用某种标识符来进行操作,但却无法访问其中存储的敏感信息时,令牌化技术就显得尤为有用。
各种方法的比较
选择哪种方法取决于应用程序的实际需求。
| 方法 | 相等性查询 | 。可逆性 | >信息泄露风险 | >典型应用场景 |
|---|---|---|---|---|
| 随机加密 | ❌ | ✅ | 低 | 一般性的加密数据 |
| 确定性加密 | ✅ | ✅ | 存在信息泄露风险 | 用于进行相等性查询 |
| HMAC | ✅ | ❌ | 存在信息泄露风险 | 用于进行相等性匹配,但不支持数据解密 |
| 令牌化 | ✅ | 通常通过专门的令牌管理系统来存储令牌 | 具体效果取决于设计方式 | 适用于系统间共享标识符的场景 |
并没有一种普遍适用的“最佳”方法。
关键的问题是:下游系统实际上需要对这些敏感数据执行哪些操作?
访问控制仍然至关重要
加密仅仅是保护个人身份信息的一种手段。即使数据已经经过了加密处理,仍然需要采取以下措施:
严格的身份认证与授权政策
最小权限访问原则
对密钥使用的严格管控
加密密钥的定期轮换机制
审计日志记录功能
数据分类管理
网络访问控制措施
安全的秘密管理流程
数据保留与删除策略
实时监控与警报机制
例如,分析人员可能被允许查询加密后的标识符,但并不被允许解密整个社会安全号码字段。
这是一个非常重要的区别:能够查询加密后的数据,并不意味着就能够解密这些数据。
从数据流处理过程中我们学到了什么
对于我们的数据流处理系统而言,关键挑战并不只是:
“如何对社会安全号码进行加密?”
更重要的问题其实是:
“我们如何在满足合法分析需求的同时保护SSN呢?”
这种区分会改变系统的架构设计。在实际的设计中,需要考虑以下因素:
哪些数据属于敏感信息?
谁需要访问这些数据?
这些数据是否需要具备可逆性?
该系统是否需要进行等值匹配操作?
是否需要支持范围查询或其他类型的查询?
哪些信息可以安全地传递给下游系统?
加密密钥应该存储在哪里?
应该如何对密钥进行分离和轮换管理?
数据传输流程在本地能够完成哪些加密处理操作?
在托管式的KMS或HSM中,需要执行哪些加密相关操作?
一旦这些问题得到了解答,加密机制就不再仅仅是一个库的选择问题,而成为架构设计中的一个重要决策。
关键要点
在设计包含敏感个人信息的数据传输流程时,有几点关键内容需要牢记:
首先,AES是一种基本的加密算法。其加密模式会决定诸如随机数生成机制等重要属性。
其次,随机化加密能够有效防止等值模式信息泄露,但无法直接支持确定性的等值搜索操作。
确定性加密虽然可以实现等值匹配,但却会暴露重复数据的信息;此外,它也不自动支持范围查询、前缀查询或任意类型的搜索操作。
接下来,可以使用HKDF算法从根密钥中生成多个相互独立的加密密钥。这种密钥分离机制能够有效降低某个加密环境被破坏所带来的影响。
KMS和HSM能够提供安全的密钥管理功能,并为数据加密设置明确的边界。
当只需要进行等值匹配时,HMAC可能比可逆加密更为合适。
通过令牌化技术,可以将敏感标识信息与下游系统隔离开来。
最后,请不要忘记:加密措施必须与身份认证、审计、监控以及最小权限访问策略相结合才能发挥最佳效果。
最重要的是:目标并不是简单地对敏感数据进行加密,而是要设计出一个既能保护敏感数据,又能确保合法业务操作能够安全进行的系统。
这才是构建安全、大规模数据传输流程时真正需要面对的挑战。
相关文章
如何将结构化数据(JSON-LD)添加到Next.js网站中并进行验证
结构化数据对搜索引擎来说一直都非常重要。当搜索引擎读取你的页面时,它看到的是HTML代码:标题、段落、日期以及名称等等。 结构化数据能够直接告诉搜索引擎这些内容的含义。例如,这个页面是一篇文章,这是它的标题,这篇文章是由某个人撰写的,并且发布于某个特定的日期。 对我来说,搜索引擎优化并不是一个需要简单勾选的步骤。我希望自己创建的产品和网站能够被人们找到,并且在被找到之后也能被正确理解。 因此,只要合适,我就会在每一页中添加结构化数据。而且我认为,随着人工智能系统开始根据网页内容来回答问题,结构化数据的重要性只会越来越明显,而不会减弱。 在Next.js应用程序中,没有任何工具会自动为你生成这些
阅读全文
掌握现代React路由技术:TanStack Router快速入门教程
在现代Web应用中,路由机制已经远远超越了仅仅根据URL路径来渲染组件的范畴。如今的开发者们渴望获得端到端的类型安全性、自动化的代码拆分功能、无缝的URL搜索参数管理机制,以及高效的数据获取方式,而无需被繁琐的`useEffect`钩子所困扰。 TanStack Router是一个功能强大的路由框架,它能够提供100%的TypeScript类型安全性,并确保在代码正式投入生产之前就能发现其中存在的错误。 我们最近在freeCodeCamp.org的YouTube频道上发布了一门全面的实践课程: TanStack Router课程——加载器、认证与类型安全的路由机制 ,该课程由Tapascrip
阅读全文
API认证与授权机制:深入探讨其工作原理、权衡因素以及可能出现的故障类型
每种API都包含某种形式的认证机制。但仅仅拥有认证机制与正确实施这一机制是两回事。 我曾经见过一些生产环境中的系统:在这些系统中,JWT令牌没有过期时间限制;有些系统的API密钥被硬编码在源代码中,并被提交到了公共代码仓库中;还有一些系统在使用OAuth重定向URL时使用了通配符;还有些系统在处理金融相关的API时使用了基本认证机制,而这些API本应通过HTTPS进行传输,但却没有人对此进行检查。 上述每一个情况都构成了潜在的安全漏洞,随时可能被恶意利用。 这些问题的产生,并非源于粗心的工程师。而是那些虽然了解各种认证机制的工作原理,却不了解它们在出现故障时会如何导致问题发生的工程师。没有人告
阅读全文
Aspire 13.6版本新增了持续性的仪表盘数据监控功能,并支持原生Java程序及Rust语言程序的运行。
微软发布了Aspire 13.6版本。此次更新中,控制面板开始使用SQLite来存储相关数据,而且每个应用程序最多可以记录10次测试结果。新版本还为Java和Rust语言提供了预发布版本的运行环境包,同时增加了可移植的文件路径设置以及新的命令行选项。值得注意的变化还包括:对于本地的MongoDB资源,系统现在会自动启用TLS加密功能;此外,默认使用的Cosmos DB模拟器镜像也进行了更新。 作者:Almir Vuk
阅读全文