在PHP中从物理内存中消除变量的值

时间:2012-04-10 12:11:15

标签: php memory encryption

一般问题是:在PHP中取消设置该变量后,是否可以从物理内存中删除String变量的值?

问题源于安全标准的某些要求(在处理某些重要数据时,应该无法将数据从内存转储到磁盘)。根据“Is memory encrypted?”主题,没有好方法可以加密内存中的数据。

因此,当在PHP中取消设置String变量时,您无法确定内存中的数据是否被覆盖。关于为变量设置新值的相同故事。

因此,如果可以在不更改unset方法的核心代码的情况下从内存中清除变量值,我感兴趣吗?

3 个答案:

答案 0 :(得分:4)

首先,我不确定擦除字符串是否符合您所描述的安全要求,因为理论上仍然可以在字符串被擦除之前转储内存。但是无论如何都无法满足,因为如果不将数据存储在内存中就无法处理数据。

无论如何,如果你想确保字符串被擦除,我认为在PHP中这样做的唯一方法是遍历字符串并修改每个字符:记住,内存的内容在被覆盖之前不会消失,甚至如果你没有引用变量并且PHP已经运行了。

我相信这会奏效:

for( $i=0; $i < strlen($str); $i++ )
    $str[$i] = 'x';

答案 1 :(得分:0)

使用PHP 5.6进行了一些测试:

<?php
     $cc = 'AAAABBBBCCCCDDDD';
     #v1:  unset($cc);
     #v2:  $cc=null;
     #v3:  for( $i=0; $i < strlen($cc); $i++ ) $cc[$i] = 'x';
     sleep(500); // enough time for taking script pid and run the memory dump
?>

尝试上述脚本的每个版本(启用#v1,启用#v2,启用#v3); 转储进程的内存(请参阅https://serverfault.com/a/408929/374467),并且'AAAABBBBCCCCDDDD'字符串始终显示在生成的二进制文件中(包含进程内存)。当$ cc值作为命令行参数($ argv)发送时也会进行测试。结果相同。

到目前为止,我发现在PHP中没有可靠的方法。

答案 2 :(得分:-2)

据我所知,问题不在于使用unset()或PHP的垃圾收集器,而是确保已使用的内存实际上已清除物理级别?

简单方法 - 在取消设置之前将其设置为null (或任何其他值)请参阅What's better at freeing memory with PHP: unset() or $var = null

硬和supid方式是用垃圾分配所有php内存,以确保它被覆盖,但我不确定虚拟内存是否在预定义的diapason上修复,或者根据进程需要进行更改。