我在Ocaml写了一个密码管理器.为了使其尽可能安全,我想在内存中存储一个字符串(加密密钥),以便它可以被覆盖.由于Ocaml是通过值传递的,并且有一个垃圾收集器,这已经证明是困难的.我加密所有缓冲区和变量,但我仍然需要存储"会话密钥"才能执行此操作.为了防止这种情况被自动密钥搜索程序检测到或放入交换中,它是使用随机增量从缓冲区中的一堆随机数据组合而成.实际上,我需要的只是一个变量,可以在组合密钥传递到Nocrypto库之前几秒钟被覆盖...参考是否适用于此?
根据这个cornell"Refs and Arrays"页面,refs是可变的,并且与C中的指针类似.也就是说,我还发现了一个堆栈溢出答案,讨论Ocaml refs,其中答案提到"它们就像指向新分配的指针记忆".这是否意味着每一次,它只是在内存中分配一个新东西,而不是实际改变内存中的东西?如果是这样,你就无法真正"覆盖"裁判.
我遇到的其他可能的解决方案是Bigarrays和"自定义块".我不完全确定"自定义块"是否实际上是在垃圾收集范围之外分配的.他们似乎习惯于访问外部C代码.他们被垃圾收集器复制了吗?它们会被"覆盖"吗?在内存中也存在"不透明字节"和不透明对象的概念.我很难绕过这一切如何融合在一起.关于堆栈溢出的内存中自定义块的一个有用但令人困惑的(对我而言)是:自定义块是否曾在内存中复制过?答案说他们可以四处走动.即便如此,他们会被覆盖吗?
最后一个可能的解决方案是使用像Nocrypto库那样的Cstruct来存储它.他们在这个github问题中讨论它:秘密材料擦除提问者声明:
"当然,大多数关键材料是Cstruct.t,它是一个Bigarray.Array1.t,它在GC堆之外分配"
这甚至是正确的吗?如果是这样,我似乎无法找到实际执行此操作的源文件.我对Ocaml和一般的函数式编程都很陌生.如果你很好奇,我的程序就位于github:ocaml-pass