背景:我在数据库中使用AES(即对称加密)加密了一些数据.在(假设的)安全且隔离的Linux机器上运行的服务器端应用程序使用此数据.它从DB读取加密数据,并写回加密数据,仅处理内存中未加密的数据.因此,为了做到这一点,应用程序需要将密钥存储在内存中.
问题是,这有什么好的最佳实践吗?保护内存中的密钥.
一些想法:
将它保存在不可挽回的内存中(对于linux:设置SHM_LOCK
为shmctl(2)
?)
将密钥拆分到多个内存位置.
加密密钥.有什么,以及如何保持...关键密钥..安全吗?
每次需要时从文件加载密钥(慢,如果恶人可以读取我们的内存,他也可以读取我们的文件)
密钥泄漏原因的一些场景:恶意获取mem dump/core dump; 检查代码导致信息泄漏的不良界限;
第一个似乎是一个很好而且很简单的事情,但其余的怎么样?其他想法?任何标准规格/最佳实践?
感谢您的任何意见!
一切都取决于你的偏执程度和关键/数据的敏感性.在极端情况下,只要内存中有未加密的密钥,就可以使用冷启动技术检索它.在frozencache有一个有趣的发展,试图打败它.我只是随便读它,没有在实践中尝试,但它似乎是一个有趣的尝试方法.
尽管 - (1),(2),(3)看起来合理,但是锡箔帽脱落了.(4)由于你提到的原因,不会精确切割它.(不仅速度慢,而且假设您读入堆栈,使用不同的堆栈深度,密钥可能会多次显示).
假设解密数据是值得的,它将在可交换内存中,你肯定也应该加密交换本身.此外,root,/ tmp分区也应加密.这是一个相当标准的设置,在大多数操作系统指南中都可以使用.
然后,当然,您希望确保机器本身的高水平物理安全性并最大限度地减少其执行的功能 - 代码运行越少,曝光越少.您还可能希望了解如何绝对最小化远程访问此计算机的可能性 - 即使用基于RSA密钥的ssh,该ssh将被另一个主机控制的另一个ACL阻止.在能够登录到第二个主机之前,portknocking可以用作身份验证的附加向量之一.为了确保如果主机被破坏,更难以得到的数据输出,确保该主机不具备到互联网的直接路由连接.一般来说,你越是痛苦地获取敏感数据,人们去那里的机会就越少,但是这也会让普通用户的生活变得痛苦 - 所以需要有一个平衡.
如果应用程序严重且涉及的事物数量很多,最好构建更明确的整体威胁模型,并查看可以预见的可能的攻击向量,并验证您的设置是否有效地处理它们.(并且不要忘记包括人为因素 :-)
更新:实际上,您可以使用专用硬件来处理加密/解密.然后你不必处理密钥的存储 - 参见Hamish的回答.
如果您认真对待安全性,那么可以考虑使用单独的加密子系统。最好是一种经过FIPS 140-2 / 3认证的模块(认证模块列表)。
然后,将密钥保存在防篡改存储器(不可提取)中,并在加密边界内执行所有加密操作。
昂贵,但对于某些应用程序是必需的。