我正在为数据库中的敏感数据编写加密序列。
目前,我正在根据 UserId 获取 GUID,并将其通过哈希处理。然后,我通过 Rfc2898DeriveBytes 运行哈希来获取 Key 和 IV,然后使用 Rijndael 函数对数据进行加密。
我的代码如下所示:
var salt = new byte[] { 1, 2, 23, 234, 37, 48, 134, 63, 248, 4 };
const int iterations = 1000;
using (var rfc2898DeriveBytes = new Rfc2898DeriveBytes(GenerateHash("2525"), salt, iterations)) {
_key = rfc2898DeriveBytes.GetBytes(32);
_iv = rfc2898DeriveBytes.GetBytes(16);
}
Run Code Online (Sandbox Code Playgroud)
然后,我传递 _key 和 _iv 来解密或加密数据。我的目标是让每个用户在每个会话中始终可以访问他们的唯一密钥。话虽如此,什么可以被随机化并且仍然保持这个功能呢?我是否总是必须使用相同的盐和相同的 IV 来获取我想要的数据?
Rfc2898DeriveBytes是 PBKDF2 的实现。显然,RFC 2898 是对定义基于密码的密钥派生函数的标准的引用。请注意,该标准比 KDF 更广泛;它的完整标题是“PKCS #5:基于密码的加密规范,版本 2.0”。
PBKDF2 是定义 PBKDF / PBKDF1 的 PKCS#5 v1 的后继者。1是在PBKDF2产生后才添加的。该类PasswordDeriveBytes是 PBKDF1 的实现。它不应该再被使用,因为 KDF 已经过时,而且微软严重搞砸了实现;如果请求的底层哈希(SHA-1)的输出超过 20 个字节,它可能会重复输出密钥材料。
除了用作 KDF 之外,PBKDF2 还可以用作密码哈希函数,其中哈希值而不是密码存储在数据库中。这样就可以验证密码,而即使对手检索到哈希数据,也无法轻松检索到密码。后续RFC 8018对此进行了描述,其中包含该协议的 2.1 版本。
在内部,PBKDF2 只是对密码和盐的哈希函数的重复。迭代次数是工作因子;它指定了在计算一个哈希值之前你(和对手)必须做多少工作。盐确保彩虹表攻击是不可能的,并且相同的密码(不同用户的)不会导致相同的哈希值。
由于设计错误,如果需要多个哈希输出,则需要重复全部工作量,因此不建议从中请求比哈希函数的输出更多的数据。在这种情况下,最好使用另一种方法来扩展输出密钥材料(字节),例如 HKDF-Expand。
对问题中代码的观察:
GenerateHash方法是虚假的,Rfc2898DeriveBytes将为您执行此操作;只是一般提示,仅使用生成的密钥来加密由安全随机函数创建的数据特定密钥。然后您甚至不需要担心 IV,并且您可以通过解密数据特定密钥并使用新密钥对其进行加密来“重新加密”。
| 归档时间: |
|
| 查看次数: |
3124 次 |
| 最近记录: |