问题 针对冷启动攻击:如何在Haskell中抑制敏感信息


在程序退出后,有没有办法确保密钥材料从内存中安全擦除?能够手动擦除并保持程序运行会更好。由于Haskell使用自动垃圾收集(如果有大量可用内存可能根本不会发生?),我认为第二项任务是不可能的。能用这个目的的东西能用FFI实现吗?


5177
2017-08-13 10:15


起源

是的,冷启动攻击是如此常见,你不得不担心它们。您可以使用ST,在STRef中保存数据并在使用后对其进行加扰。 Dunno,如果你可以在STRefs背后的内存。 - Cat Plus Plus


答案:


GHC可以在不再需要时将内存返回给操作系统,因此仅在退出时消隐内存将无法实现您的目标。垃圾收集是一项复杂的业务,但通常无法确保安全数据的旧副本不会返回到操作系统内存池。

但是,在将内存分配给另一个进程之前,操作系统将清空内存。如果您不相信操作系统以保证您的内存安全,那么您就会遇到更大的问题。

我不确定你的意思是“不可靠”; Haskell GC是可靠的,但该程序对正在发生的事情的可见度相对较低。

但是,如果您只关注加密密钥而不是大而复杂的数据结构,那么生活会变得更好。你可以用一个 外国指针 指向密钥的内存位置,然后将该位内存消隐到终结器的一部分中。你甚至可以编写一些分配内存块的代码, 并且mlocks 它,然后根据请求将外部指针交给该内存的密钥大小的块,并使用擦除密钥的终结器。这可能会做你想要的。

ForeignPtr的要点是保证GC不会移动或重新解释它。


14
2017-08-13 11:06



感谢您的回答。由于我不太熟悉所有这些“外国”的东西,我会等着看是否有一个指向现有代码的答案会出现并接受你的答案。操作系统在将内存交给其他进程之前清除内存对此没有帮助,因为一个冷却只需拔出插头并将RAM模块放到另一台机器上。如果它听起来像是太安全了,那么考虑(笔记本电脑)磁盘加密 - 在挂起之前将未加密的密钥材料从内存中清除是个不错的主意。我还澄清了我不愿意在原帖中依赖自动GC。 - Andres
ForeignPtr没有什么可怕的困难。看到 en.wikibooks.org/wiki/Haskell/FFI 作为教程。 - Paul Johnson
@Andreas不会拔掉插头清空其数据的RAM吗? - amindfv
@amindfv为了使RAM数据保持不变,它会被定期读取和重写。但是,不擦除RAM没有擦除它,数据会随着时间的推移逐渐消失。今天使用的大多数RAM都没有足够快地褪色以防止复制它,即使它在室温下也可以先冻结它以使其持续更长时间。关于这个问题有一篇论文在 citp.princeton.edu/research/memory - Andres
有些攻击不涉及断电。例如,您可以插入可启动的拇指驱动器并按下重置;拇指驱动器启动到一个将内存映像转储到文件的小程序。 OHCI over firewire的一些实现允许连接的设备发送DMA命令,该命令允许仅通过插入设备来对整个RAM进行成像。因此,最小化关键数据保存在RAM中的时间是一件好事。 - Paul Johnson