Haskell或OCML能否处理敏感数据而不通过垃圾收集泄露?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Haskell或OCML能否处理敏感数据而不通过垃圾收集泄露?相关的知识,希望对你有一定的参考价值。
我会做这样的事情(伪代码)。
1. load sensitive encrypted data from file
2. decrypt the data
3. do something with the unencrypted data
4. override the data safely / securely (for example with random data)
敏感数据在内存中以明文形式存在(未加密)的时间应该尽可能的短。
明文数据不能以任何方式泄露。
A. 这样的程序可以用Haskell或OCAML编写吗?
B. 能否防止数据被泄露,即被垃圾收集器在后台默默复制?
C. 能否在内存中适当覆盖明文数据?
据我所知,垃圾收集器(GC)可以在后台默默地对数据进行复制。我猜测这是通过代入式GC算法完成的,但我不确定。
我知道,如果攻击者能够在正确的时间状态下获得程序的内存,那么攻击者仍然有可能获得明文数据。我只是考虑这样做会提高安全性,因为我没有控制上下文(即操作系统,交换等)。
我已经在评论中提到过这个问题,但我认为这是一个非常好的问题,值得回答。
已经有一个数据类型 ScrubbedBytes
具有以下属性。
- 它的分配方式是:
newAlignedPinnedByteArray#
这意味着,当新分配的MutableByteArray#
在你的代码中任何地方被引用,它都不会被GCed,但也不会被移动或复制。 - 在分配时,一个弱指针会被创建,并使用
mkWeak#
并在新分配的内存中添加一个定标器。这意味着,每当洗刷过的字节在你的代码中不再被引用时,在GC deallocates内存之前,一个洗刷器将被调用,它将向内存中写入0。 - 平等不会短路,从而防范定时攻击。
这个洗涤器有一个小问题。有一个小的机会,它不会被执行,特别是如果程序在GC应该清理内存之前退出。(查看更多关于弱点的信息.) 因此,我建议使用 bracket
模式。以下是你如何用 primitive
包。
import Control.Exception
import Control.Monad.Primitive (RealWorld)
import qualified Data.Primitive.ByteArray as BA
withScrubbedMutableByteArray ::
Int -- ^ Number of bytes
-> (BA.MutableByteArray RealWorld -> IO a)
-- ^ Action to execute
-> IO a
withScrubbedMutableByteArray c f = do
mba <- BA.newPinnedByteArray c
f mba `finally` BA.setByteArray mba 0 c (0 :: Word8)
为什么要使用 finally
是比较安全的,因为你会有更强的保证,内存会被清零。例如用户在正确的设置中按下Ctrl-C不会阻止洗涤器运行。
在OCaml中,使用Bigarrays可以很容易地做到这一点,它不受GC的管理,从不复制,也从不被它检查。你可以使用 Unix.map_file 加载它和 凸轮结构 来很好地处理加载的数据(如果它是结构化的)。OCaml被广泛用于编写低级别的安全相关代码,请参见《安全》。蜃楼 项目(它有大量的密码学相关库)。ocaml-tls TLS协议在OCaml中的纯粹实现,和 珠峰项目 其中使用 OCaml 作为目标语言。
当解密encrypting和以其他方式处理秘密数据时,你应该小心,不要把它放在一个盒子类型中,包括字符串和int64整数。如果你将看看 蜃楼-加密技术 你会发现,所有的算法都是只用整数来实现的,整数被表示为即时数,而GC从来没有接触过。
以上是关于Haskell或OCML能否处理敏感数据而不通过垃圾收集泄露?的主要内容,如果未能解决你的问题,请参考以下文章
在 Haskell 中添加存储为 0 和 1 列表的两个二进制数,而不使用反向
Haskell:如何将 IO 输入字符串解析为 Float(或 Int 或其他)?