如何安全地将c ++变量保存在RAM中?

Ehs*_*hmi 14 c++ security encryption variables ram

我正在开发一个C++应用程序,它将一些用户密钥保存在RAM中.这个密钥非常敏感,我必须尽量减少对它们进行任何攻击的风险.
我正在使用一个字符数组来存储这些键,我已经阅读了一些关于在CPU寄存器甚至CPU缓存中存储变量的内容(即使用C++ register关键字),但似乎没有一种保证的方法来强制应用程序存储一些它是RAM之外的变量(我的意思是在CPU寄存器或缓存中).
任何人都可以建议一个好的方法来做这个或建议任何其他解决方案将这些密钥安全地保存在RAM中(我正在寻找一个独立于操作系统的解决方案)?

Nik*_*lis 17

你的意图可能很高尚,但也被误导了.简短的回答是,在通用系统(即商品处理器/主板和通用O/S)上实际上没有办法做你想要的.即使你可以,不知何故,强迫事情只存储在CPU上,它仍然没有真正的帮助.这只会是一个小麻烦.

更一般地说,对于保护内存的问题,有O/S特定的解决方案来指示不应将块内存写入页面文件,例如VirtualLockWindows上的函数.如果您正在进行加密并在该内存中保存敏感数据,那么这些值得使用.

最后一件事:我要指出的是,我担心的是你对register关键字及其安全影响存在根本性的误解; 记住它是一个暗示,它不会 - 实际上,它不能 - 迫使任何东西实际存储在寄存器或其他任何地方.

现在,这本身并不是什么大问题,但这是一个问题,因为它表明你并没有真正掌握安全工程或风险分析,如果你正在设计或实施这是一个大问题一个真实的加密解决方案.坦率地说,你的帖子(至少对我来说)表明你还没有准备好构建或实现这样一个系统.

  • OP不寻求安全保证,只是最小化.你过于苛刻,特别是说他不合格.我们都在这里学习. (10认同)
  • 我想说如果它们在寄存器中,它会使系统更容易攻击.如果您知道数据的位置,那就是成功的一半.RAM优于CPU的唯一优势是搜索有很多优势(但如果你知道它在哪里,那么提取它(使用正确的工具)并不困难. (4认同)
  • @Freedom_Ben他担心的风险**不可能**使用软件或语言关键词进行管理.指出这一点并不是很苛刻,或者告诉他,他正在提出错误的问题并根据不成立的假设进行操作. (4认同)

Raf*_*sta 9

您无法消除风险,但可以减轻风险.

创建一个静态内存区域,这是您存储明文密钥的唯一位置.并创建一个随机数据缓冲区,您将使用该缓冲区来清除未存储在此静态缓冲区中的任何键.

无论何时从密钥文件或其他内容读取内存中的密钥,您只能将其直接读入此静态缓冲区,xor随机数据并将其复制到您需要的任何位置,并立即用零清除缓冲区.

您可以通过比较它们的蒙版版本来比较任意两个键.您甚至可以比较屏蔽键的哈希值.

如果你需要操作明文密钥 - 例如生成一个哈希或验证它们的密钥以某种方式将掩盖的xor'ed密钥加载到这个静态缓冲区中,xor它回到明文并使用它.然后将零写回缓冲区.

取消屏蔽,操作和重新屏蔽的操作应该很快.不要让缓冲区长时间未被遮盖.

如果有人要尝试冷启动攻击,拔掉硬件上的插头,并检查内存芯片,那么只有一个缓冲区可能存有明文密钥,并且在冷启动攻击缓冲区的特定瞬间可能存在会是空的.

当对键进行操作时,您甚至可以在需要它之前解除键的一个单词,以便验证键,使得完整的键永远不会存储在该缓冲区中.

@update:我只是想在下面的评论中提出一些批评:

"通过默默无闻的安全"这一短语通常被误解.在安全算法的正式分析中,"隐藏"或隐藏不具有密码安全性的数据的方法不会增加加密算法的正式安全性.在这种情况下也是如此.鉴于密钥存储在用户计算机上,并且必须由该计算机在该计算机上使用,因此无法使该计算机上的密钥加密安全.无论您在某个时刻使用什么进程来隐藏或锁定数据,程序都必须使用它,并且确定的黑客可以在代码中放置断点并观察程序何时使用数据.但是在这个帖子中没有任何建议可以消除这种风险.

有人建议OP找到一种方法来使用带有锁定内存芯片的特殊硬件或一些锁定芯片的操作系统方法.这在加密方面不再安全.最终,如果您对机器有物理访问权限,那么足够坚定的黑客可以在内存总线上使用逻辑分析仪并恢复任何数据.除了OP已经声明目标系统没有这样的专用硬件.

但这并不意味着您无法采取措施来降低风险.使用最简单的访问密钥 - 密码.如果您可以对机器进行物理访问,则可以将其放入密钥记录器中,或者获取正在运行的程序的内存转储等.因此,正确地说,密码不会比粘贴在键盘上的便签上用明文写的密码更安全.然而,每个人都知道在粘滞便笺上保留密码是一个坏主意,这对程序以明文回复用户密码是不好的做法.当然,实际上,这大大降低了攻击者的标准.然而,正式的带有密码的便利贴也同样安全.

我上面提出的建议具有真正的安全优势.除了安全密钥的"xor"屏蔽外,其他细节都不重要.并且有一些方法可以使这个过程变得更好.Xor'ing键将限制程序员必须考虑作为攻击向量的位置数.一旦密钥是xord,你可以在你的程序中拥有不同的密钥,你可以复制它们,将它们写入文件,通过网络发送等等.除非攻击者拥有xor缓冲区,否则这些都不会危害你的程序.所以有一个单一的缓冲你需要担心.然后,您可以放松系统中的每个其他缓冲区.(你可以mlock或VirtualLock那一个缓冲区)

一旦清除了xor缓冲区,就可以永久安全地消除攻击者从程序内存转储中恢复任何密钥的可能性.您可以根据地点数量和可以恢复钥匙的时间来限制您的曝光率.而且您正在建立一个系统,允许您轻松使用密钥,而不必担心每个操作对象都包含关于可以轻松恢复密钥的方法的密钥.

因此,您可以想象一个系统,其中键重新计算xor缓冲区,并且当不再需要所有键时,您将零并删除xor缓冲区,并且所有键都变为无效且无法访问,而无需您追踪它们并担心是否存在内存页面被换出并仍然保留明文密钥.

您也不必随意保留随机数据的缓冲区.例如,您可以使用加密安全随机数生成器,并根据需要使用单个随机种子生成xor缓冲区.攻击者可以恢复密钥的唯一方法是访问单个生成器种子.

您还可以根据需要在堆栈上分配明文缓冲区,并在完成时将其归零,以使堆栈极不可能离开芯片缓存.如果完整的密钥从未被解码,但是根据需要一次解码一个字,即使访问堆栈缓冲区也不会显示密钥.

  • @david:你说"有更好的解决方案" - 但是你建议使用"mlock".但这提供了额外的加密安全性.在这种情况下,他担心冷启动攻击 - 但如果你可以启动系统 - 你可以启动你想要的任何东西 - 所以你甚至不需要root/admin访问扫描内存.所有密钥都将以明文形式存储在内存中.你对这种易受已知明文攻击的影响也是错误的 - 掩码位可以根据你的喜好随时改变. (4认同)
  • 很好的答案.这是迄今为止最好的一个.+1因为我只能投票一次. (3认同)
  • 这绝对没有任何意义.由于多种原因,XOR方案是愚蠢的.一个是攻击者所要做的就是找到存储XOR主数据的地方,做XOR,就是这样.另一个是它完全容易受到诸如已知明文之类的各种攻击.它可能不会造成任何伤害,前提是没有人依赖它,也会做出其他人提出的各种理智的事情 - 但如果有人希望这能提供一定程度的安全性并依赖它,那么非常糟糕的事情就会发生. (2认同)
  • 这里发表的一些批评似乎是“没有很好的解决方案,所以您甚至不应该尝试”。大概您也不锁住您的房子的前门,因为砸碎窗户并以这种方式进入是不容易的。 (2认同)
  • @RafaelBaptista:我不会在SO评论中与你辩论.这是一个非常糟糕的主意,你让自己看起来很愚蠢.**易受已知明文攻击的影响,因为如果您知道密钥的明文,则可以使用XORed密钥对明文密钥进行异或并恢复掩码.如果这是一个好主意,真正的程序会以这种方式做事,但事实并非如此. (2认同)

Dav*_*rtz 5

没有独立于平台的解决方案.您要解决的所有威胁都是特定于平台的,因此解决方案也是如此.没有法律要求每个CPU都有寄存器.没有法律要求CPU拥有缓存.另一个程序访问程序RAM的能力,实际上是其他程序的存在,是平台细节.

您可以创建一些功能,如"分配安全内存"(默认调用malloc)和"免费安全内存"(默认调用memset然后free),然后使用它们.您可能需要在需要其他操作的平台上执行其他操作(例如锁定内存以防止密钥在交换中清空).