Haskell或OCML能否处理敏感数据而不通过垃圾收集泄露?

问题描述 投票:5回答:1

我会做这样的事情(伪代码)。

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算法完成的,但我不确定。

我知道,如果攻击者能够在正确的时间状态下获得程序的内存,那么攻击者仍然有可能获得明文数据。我只是考虑这样做会提高安全性,因为我没有控制上下文(即操作系统,交换等)。

haskell memory-management garbage-collection ocaml
1个回答
10
投票

我已经在评论中提到过这个问题,但我认为这是一个非常好的问题,值得回答。

已经有一个数据类型 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不会阻止洗涤器运行。


5
投票

在OCaml中,使用Bigarrays可以很容易地做到这一点,它不受GC的管理,从不复制,也从不被它检查。你可以使用 Unix.map_file 加载它和 凸轮结构 来很好地处理加载的数据(如果它是结构化的)。OCaml被广泛用于编写低级别的安全相关代码,请参见《安全》。蜃楼 项目(它有大量的密码学相关库)。ocaml-tls TLS协议在OCaml中的纯粹实现,和 珠峰项目 其中使用 OCaml 作为目标语言。

当解密encrypting和以其他方式处理秘密数据时,你应该小心,不要把它放在一个盒子类型中,包括字符串和int64整数。如果你将看看 蜃楼-加密技术 你会发现,所有的算法都是只用整数来实现的,整数被表示为即时数,而GC从来没有接触过。

© www.soinside.com 2019 - 2024. All rights reserved.