【发布时间】:2015-05-03 02:40:18
【问题描述】:
我的问题是关于我实际需要在 DB 中存储什么重新加密的值,以及如何将其专门用于 GCM 的 nonce。
作为参考,这两个答案提供了加密数据的示例代码: Cbc 和 gcm。
据我了解,CBC 要求 IV 完全随机。我知道对于 CBC(以及所有加密),密钥/IV 应该始终是唯一的。如果重复,这对 CBC 来说是“坏的”,如果使用 GCM,则是一个根本缺陷。然而,GCM 不需要它是完全随机的,只要它从不重复即可。
根据这些假设,我们计划在应用程序的某处有一个“密钥”(即将密钥与数据库中的加密数据分开)。我们将每“n”个月滚动一次密钥,并且仅在生成新密钥之前将其用于“x”次加密(限制使用范围等),但是,我们将对两条或更多记录使用相同的“密钥” .因此,唯一的 key/iv 开始发挥作用。
注意:我们需要能够稍后再次读出数据并“使用”它。这不是一种加密方式。
在设计数据库时,我们将使用类似于以下的列。
CBC 模式的 DB 列(我在堆栈溢出时看到过类似的内容...抱歉找不到链接):
- ID(主键,整数)(唯一)
- 加密值
- 盐
- 迭代
- (其他...标准的东西,如创建日期等)
Gcm 模式的 Db 列:
- ID(主键,整数)(唯一)
- 加密值
- 关联文本
- (其他...标准的东西,如创建日期等)
IV/Nonce 处理问题
对于 CBC 模式,我们将使用例如Rfc2898DeriveBytes 并从中获取 IV 而不是存储它。
关于 GCM 模式,这里的想法是执行以下操作:
- 先保存记录,然后“获取”行的id
- 将行ID转换为字节[16]...例如(仅作为示例...)
var rowID = 123456789.ToString();
var tempByte = new List<byte>(16);
tempByte.AddRange
(123456789.ToString()
.Select(Convert.ToByte));
if (rowID.Length < 16)
{
for (var i = 0; i < (16 - rowID.Length); i++)
{
// Note: something to fill the rest.....
var someNewByteFromSecureRandom = new[] {Convert.ToByte(1)};
tempByte.Add(someNewByteFromSecureRandom[0]);
}
}
- 将加密数据保存到行中。
这样,对于 GCM 加密,nonce 始终是唯一的。即使我们总是使用相同的密钥,key/iv 也永远不会重复。 (注意:据我们了解,这种方法不适用于 CBC,因为它要求 iv 是真正随机的而不是计数器)
基本上,这两种方法都有问题吗? (在使用 GCM 方法大纲获取 nonce 时,忽略记录的明显双重保存(插入/更新))。我们是否保存了我们不应该保存的东西?我们不是在保存我们应该保存的东西吗?
【问题讨论】:
-
这更多是关于安全数据库设计而不是编程。因此,我会推荐 IT security 而不是 StackOverflow(如果您决定搬家,请在安全站点上创建一个帐户,输入一个新问题,在此处编辑问题复制内容,粘贴到新问题中,删除旧问题并发布新问题)。
-
如果您这样做,请告诉我 - 我将在安全站点删除我的答案和答案。
标签: c# database-design cryptography