背景
我正在使用原生C ++ 11中的一个简单应用程序,该应用程序使用Microsoft的Cassablanca REST框架与各种远程端点进行通信。为此,我必须使用由目标API提供的一些秘密以加密方式签署各种请求。通过链接Cassablanca我已经拥有OpenSSL,因此实际的加密是相当直接的。
现在,棘手的部分是如何自己存储秘密。我的计划是AES使用来自用户大脑的对称密钥(读取:密码)加密一个带有所有好东西的JSON文件,这样它就不必存储在磁盘上。
问题
在应用程序执行期间将解密的密钥存储在内存中的安全方法是什么?这不是另一种"如何在磁盘上存储机密以便用户不会这样做?我必须做任何事情"问题
我最担心的是,有人能够在外部检查我的应用程序的内存并找到包含好东西的适当区域。我知道Windows提供了信用存储和受保护的内存,但我在Linux上,如果可能的话,更喜欢与平台无关的解决方案。这也很有可能会部署到VM群集中,因此受保护的内存可能只会购买有限的保证(但仍然比没有好)。
最后,我知道任何加密系统都可以通过足够大的资金+时间或足够大的橡胶软管来克服。话虽这么说,我仍然希望尽可能安全地进行Good™编码练习。
我的约束是:
必须能够快速访问用于签署各种请求的机密。毫秒数在这里,但如果安全性得到真正改善,我愿意接受减速。
我更喜欢最少的外部库,并尽可能使用原生C ++ 11。我觉得这应该是我已经拥有的(Cassablanca需要OpenSSL,Boost,libcrypt)。
最后,它应该能够容纳相当多的秘密/请求。我的应用程序域基本上是一个巨大的并行化问题,可扩展性是关键。
我已经知道的事情:
永远不要将敏感材料存储在未加密的磁盘上。这包括使用磁盘支持的容器等等。
一个古老但有用的技巧:附加调试器实例以防止从外部进程进行远程调试。
构建没有调试符号并剥离最终可执行文件。
尽量减少应用程序对数据的访问权限,仅限于真正需要它的部分。
一旦不再需要敏感信息,请立即销毁(例如,解密完成后,请立即输出用户密码等)。
不要相信任何人为我消毒记忆。使用NULL / garbage手动覆盖区域。
类似问题
PHP具体并建议写一些不在PHP中的东西来存储凭证......这正是我试图解决的问题。
Android应用程序生命周期特定。我已经知道我的秘密的存储持续时间将是应用程序的生命周期。
答案 0 :(得分:1)
我会有一个静态内存区域(应用程序中的较大缓冲区,其中包含每个应用程序启动加密密钥。
这会导致....
该方案保留三个存储区域,加密秘密是静态的,以及部分图像存储器。
一般应用程序端数据 - 使用普通的新建/删除。
加密数据,使用自定义新/删除,这是一个mmap,并且不会与普通的新/删除共享地址
答案 1 :(得分:-1)
LibSodium是您需要的图书馆:https://download.libsodium.org/doc/helpers/memory_management.html
不知道这是否可以在每个可能的平台上使用,但在大多数情况下,这可以帮助您实现目标。