如何安全地处理AES“密钥”和“IV”值

时间:2013-08-19 22:29:56

标签: c# .net encryption cryptography aes

如果我使用AES(System.Security.Cryptography)简单地加密和解密SQL服务器中的blob或memo字段,那么我在哪里将“Key”和“IV”值存储在服务器上? (文件,Regkey,Dbase,......)

那些AES“Key”和“IV”值的保护是什么?

背景问题更多:如果“他们”攻击服务器并获得dbase ...那么可能他们也可以进入加密程序的程序(它在同一台服务器上,无法帮助它) ...如果“他们”非常好,那么他们会注意到存储“Key”和“IV”值的位置......(.NET 4.5 ILSPY)并且所有内容都可以再次解密。

请指教?你们如何处理AES“Key”和“IV”值?

Ps:这不是关于pwd字段......所以,它不是关于哈希......它的纯数据加密。

5 个答案:

答案 0 :(得分:27)

IV已被其他答案彻底涵盖,因此我将专注于存储密钥。

首先...

  

我不能,除非它无法在软件级别的单个服务器上完成。

在软件中完成的任何操作都可以在软件中撤消。您可以根据需要在尽可能多的保险箱中加密,隐藏和锁定它,但您的应用程序仍然需要能够访问密钥。如果您的应用程序具有访问权限,那么与您的应用程序具有相同访问级别的人也可以访问它。

很长一段时间以来,开发人员一直在处理这个问题,而且没有灵丹妙药。

  

这一切都是在单一服务器环境(应用程序加dbase)中设置的,因此我无法将密钥发送/检索到第二台服务器。此外,在这种“特殊”情况下,我无法通过机器级或用户级RSA密钥容器加密密钥。

我可以想到两种可能的解决方案。

选项1:

将密钥存储在磁盘上,并在操作系统级别配置文件访问权限,以便只有运行应用程序的帐户才能读取密钥所包含的文件。该文件可以是平面文件,也可以是加密容器这是由您的应用程序知道的密码保护(由您决定,但加密容器更好)。

优点:

  • 在没有人为干预的情况下重新开始。

缺点:

  • 您必须正确执行操作系统安全性,并且没有错误的余地。
  • 具有管理员访问权限的攻击者可以获取密钥。

另一个类似的选项是使用DPAPI而不是文件来存储密钥(只要你能够根据你的“特殊情况”这样做)。这是一个内置于Windows的API,它利用您(或您的应用程序)运行的任何Windows帐户的密码来安全地存储数据。只有存储数据的Windows帐户才能检索它。

DPAPI的一个特别好的功能是,如果管理员重置用户密码(通过计算机管理),access to that users DPAPI data is lost。攻击者需要先破坏用于存储数据的实际帐户,而不必重置密码。

选项2:

要求在应用程序启动时由人输入密码短语,并从该密码短语派生加密密钥。获得密钥后,丢弃密码短语并仅将密钥保留在内存中。

优点:

  • 密钥永远不会在磁盘上。
  • 即使服务器是root用户,获取密钥也不是一项简单的任务。

缺点:

  • 无法自动重启。
  • 您可能需要与处理支持的任何人分享密码短语。
  • 您需要记住,在某些情况下,存储在中的数据可以透明地写入磁盘。

或者您可以在这两个系统之间进行折衷,其中,密码短语最初用于派生保存在内存中的加密密钥,并且只要应用程序正常重新启动,密钥就会临时写入磁盘或加密容器。重新启动完成后,应用程序将加载密钥,然后将其从临时存储中删除(如果需要,请务必覆盖存储密钥的磁盘位置,以便无法恢复)。

答案 1 :(得分:13)

经验法则是:

  • 密钥必须始终保密(不得在数据库附近)
  • 每个记录的IV必须不同。
  • IV必须“无法与随机区分”并且不可预测,最好它必须来自与您的AES密钥相同的来源;另一种选择是使用密钥加密某些值(每条记录不同)。
  • IV不需要保密

因此,您可以使用的一种方案是:

  1. 创建一个包含字段ID(唯一,整数),IV(唯一,16字节),加密(可变字节,可空)的表
  2. 要将新记录写入数据库,请创建新的唯一IV并使用空加密数据在数据库中创建新记录(以防止冲突)
  3. 使用您的机密键和步骤2中的IV加密数据(CBC或点击率模式 - 点击率更高)并更新记录。
  4. 第二步可以通过从先前记录中取出IV并使用相同的密钥加密来执行 - AES的属性将使其成为有效的随机IV。

    这将与您使用AES一样安全 - 这意味着CCA / CPA安全。它唯一不能阻止的是篡改

答案 2 :(得分:11)

IV不需要像密钥那样保密,唯一可以做的就是确保使用相同密钥加密的两个完全相同的blob产生两个完全不同的输出(所以你不能告诉同一个消息被发送两次)。许多加密系统只是将IV作为消息的第一个字节。

加密密钥是一个难以管理的事情,你可以做的最好的事情是保持数据库本身和应用程序分开,以便“如果”他们“破解服务器并获得dbase”(假设SQL注入攻击让他们做他们仍然无法解密字段本身。

答案 3 :(得分:1)

在此处隔离您的Web服务器和数据库服务器会很有帮助。您希望锁定加密密钥的访问权限(以权限方式),并将其作为SecureString保存在内存中。做不了多少。选择强密码并遵循最新的安全实践。

这也是一篇好文章Where to Store Encryption Keys MVC Application

答案 4 :(得分:0)

如果加密信息不多,请定期更新加密记录中的密码和信息,例如,可以是每天或每小时。