IV已被其他答案彻底覆盖,所以我将只关注存储密钥。
第一的...
我不能,除非它不能在软件级别的单个服务器上完成。
在软件中完成的任何事情都可以在软件中撤消。您可以在任意数量的保险箱中加密、隐藏和锁定它,但您的应用程序仍然需要能够访问密钥。如果您的应用程序具有访问权限,那么与您的应用程序具有相同访问级别的人也可以访问它。
开发人员已经处理这个问题很长时间了,并且没有灵丹妙药。
这一切都是在单个服务器环境(应用程序加 dbase)中设置的,因此我无法将密钥发送/检索到第二台服务器。此外,在这种“特殊”情况下,我无法通过机器级或用户级 RSA 密钥容器加密密钥。
我可以想到两种可能的解决方案。
选项1:
将密钥存储在磁盘上,并在操作系统级别配置文件访问权限,以便只有运行您的应用程序的帐户才能读取包含密钥的文件。该文件可以是平面文件,也可以是受保护的加密容器您的应用程序知道的密码(由您决定,但加密容器更好)。
优点:
缺点:
- 您必须正确执行操作系统安全,并且没有出错的余地。
- 具有管理员访问权限的攻击者可以获取密钥。
另一个类似的选择是使用DPAPI而不是文件来存储密钥(只要您能够在给定“特殊情况”的情况下执行此操作)。这是一个内置于 Windows 的 API,它使用您(或您的应用程序)运行的任何 Windows 帐户的密码来安全地存储数据。只有存储数据的 Windows 帐户才能检索它。
DPAPI 的一个特别好的功能是,如果管理员重置用户密码(通过计算机管理),则对该用户 DPAPI 数据的访问权限将丢失。攻击者需要首先破坏用于存储数据的实际帐户,而无需重置密码。
选项 2:
要求用户在应用程序启动时输入密码短语,并从该密码短语派生加密密钥。获得密钥后,丢弃密码短语并仅将密钥保留在内存中。
优点:
- 密钥永远不会在磁盘上。
- 即使服务器已root,获取密钥也不是一件容易的事。
缺点:
- 无法自动重新启动。
- 您可能必须与任何处理支持的人共享密码短语。
- 您需要记住,在某些情况下,存储在内存中的数据可能会透明地写入磁盘。
或者您可以在这两个系统之间进行折衷,其中,密码短语最初用于派生保存在内存中的加密密钥,并且每当应用程序正常重新启动时,密钥会临时写入磁盘或加密容器。重新启动完成后,应用程序会加载密钥,然后将其从临时存储中删除(如有必要,请确保覆盖存储密钥的磁盘位置,以便无法恢复)。