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

本文关键字:密钥 IV AES 处理 何安全 安全 | 更新日期: 2023-09-27 18:28:19

如果我使用AES(System.Security.Cryptography)来简单地加密和解密SQL服务器中的blob或memo字段,那么我应该将"Key"answers"IV"值存储在服务器上的何处?(文件,注册表项,数据库,…)

那些AES"密钥"answers"IV"值的保护又如何呢?

背景问题更多:如果"他们"入侵服务器并获得数据库。。。然后他们可能也可以访问做加密工作的程序(它在同一台服务器上,没办法)。。。如果"they"非常好,那么他们会注意到"Key"answers"IV"值存储在哪里。。。(.NET 4.5 ILSPY),所有内容都可以再次解密。

请给我建议?你们是如何处理AES"密钥"answers"IV"值的?

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

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

其他答案已经完全涵盖了IV,所以我只关注存储密钥。

首先。。。

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

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

开发人员已经处理这个问题很长时间了,没有什么灵丹妙药。

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

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

选项1:

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

优点:

  • 无需人工干预即可重新启动

缺点:

  • 你必须做好操作系统的安全,没有犯错的余地
  • 具有管理员访问权限的攻击者可以访问该密钥

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

DPAPI的一个特别好的特性是,如果管理员重置用户密码(通过计算机管理),则会丢失对该用户DPAPI数据的访问。攻击者需要在不重置密码的情况下破坏最初用于存储数据的实际帐户。

选项2:

要求一个人在应用程序启动时输入一个通行短语,并从该通行短语中导出加密密钥。一旦你有了钥匙,就放弃通行短语,只在记忆中保留钥匙。

优点:

  • 密钥从不在磁盘上
  • 即使服务器是根服务器,获取密钥也不是一项简单的任务

缺点:

  • 自动重新启动是不可能的
  • 您可能需要与任何处理支持的人员共享通行证短语
  • 您需要记住,在某些情况下,存储在内存中的数据可能会透明地写入磁盘

或者,您可以在这两个系统之间进行折衷,在这两种系统中,一开始使用通行短语来派生内存中的加密密钥,并且每当应用程序正常重启时,密钥都会临时写入磁盘或加密容器。重新启动完成后,应用程序加载密钥,然后将其从临时存储中删除(如有必要,请确保覆盖存储密钥的磁盘位置,以便无法恢复密钥)。

经验法则是:

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

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

  1. 创建一个包含字段ID(唯一,int)、IV(唯一,16字节)、Encrypted(可变字节,NULLable)的表
  2. 要将新记录写入数据库,请创建新的唯一IV,并在数据库中使用空加密数据创建新记录(以防止冲突)
  3. 使用机密密钥和步骤2的IV加密数据(CBC或CTR模式-CTR更好),并更新记录

第二步可以通过从以前的记录中提取IV并用相同的密钥加密来执行。AES的属性将使其成为有效的随机IV。

这将是安全的,你可以得到AES-意味着CCA/CPA安全。它唯一不能阻止的是篡改

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

加密密钥是一件很难管理的事情,你能做的最好的事情就是将数据库本身和应用程序分开,这样"如果"他们"入侵服务器并获取数据库"(比如SQL注入攻击让他们可以转储数据库的表),他们仍然无法自己解密字段。

将web服务器和数据库服务器分离在这里会很有帮助。您希望锁定对加密密钥的访问(权限方面),并将它们作为SecureString保存在内存中。不能做更多的事情。选择强密码并遵循最新的安全做法。

这也是一篇很好的文章,在哪里存储加密密钥MVC应用程序

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