Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
String Delphi:如何从内存中完全删除字符串_String_Delphi_Memory_Encryption - Fatal编程技术网

String Delphi:如何从内存中完全删除字符串

String Delphi:如何从内存中完全删除字符串,string,delphi,memory,encryption,String,Delphi,Memory,Encryption,现在,当我使用“WinHex”之类的程序搜索进程内存时,我可以很容易地找到未加密的字符串! 即使我尝试创建新表单来加密这个字符串,然后卸载表单,但它仍然存在 有没有办法把它完全去掉 提前感谢处理完字符串后,需要用零覆盖该字符串。像这样: Var S1:String; S2:String; begin S1:='Sensitive Data'; S2:=Crypt(S1,'encryption key'); S1:=''; FreeAndNil(S1); end; 如果您

现在,当我使用“WinHex”之类的程序搜索进程内存时,我可以很容易地找到未加密的字符串! 即使我尝试创建新表单来加密这个字符串,然后卸载表单,但它仍然存在

有没有办法把它完全去掉


提前感谢

处理完字符串后,需要用零覆盖该字符串。像这样:

Var
S1:String;
S2:String;
begin
   S1:='Sensitive Data';
   S2:=Crypt(S1,'encryption key');
   S1:='';
   FreeAndNil(S1);
end;
如果您偏执于编译器会优化ZeroMemory,那么您可以使用SecureZeroMemory。但是,Delphi编译器不会优化零内存,因此这有点没有实际意义

如果你只是写:

ZeroMemory(Pointer(s), Length(s)*SizeOf(Char));
然后,内存将按原样返回到内存管理器。然后,您无法控制内存管理器何时(如果有)重新使用或返回内存

显然,您需要对字符串的所有副本执行此操作,因此唯一明智的方法是不复制敏感数据

所有这些都无助于您问题中的代码,因为您的敏感数据是字符串文本,因此存储在可执行文件中。这种方法只能有意义地应用于动态数据。我假定您的真实程序不会将敏感数据以文字形式放置

哦,永远不要给FreeAndNil传递字符串。您只能将对象变量传递给FreeAndNil,但该过程使用了非类型化的var参数,因此编译器无法避免您的错误。

var
s := '';
S1:字符串; S2:字符串; 开始 S1:=‘敏感数据’; S2:=Crypt(S1,“加密密钥”);
唯一字符串(S1);//所有字符串文本将始终保留在内存中,因此,如果在测试项目中使用字符串文本,但在实际代码中获得用户输入,则测试将失败。如果从内存中删除字符串,将有何帮助?它已经在可执行文件中。一旦您处理完敏感数据,请覆盖它。是的,取而代之的是安全环境。你为什么用一个字符串打免费电话?您需要更好地理解。如果您在硬编码中对其进行加密,并对加密值进行硬编码。该字符串将在内存和可执行文件中清晰可见。请记住,使用正确工具的人可以在解密程序并读取密钥时停止程序。打开一个十六进制编辑器,在EXE中搜索字符串——很明显,您会看到它。如果在源之外对其进行加密,则加密字符串将可见。这不是一个安全的方法,但它确实会让人努力找到密钥。我们是否应该确保S1只通过引用传递给Crypt?@MarcusAdams:在这种情况下,这并不重要,因为字符串是引用计数的,所以它仍然是同一个内存块。需要注意的是,你上面大卫的密码会崩溃。字符串
S1
位于进程地址空间的只读页中。最好使用
BurnString
方法,该方法通过引用获取字符串,并调用
System.UniqueString
。这样,您就不必担心那些秘密引用计数为零的“常量”字符串。@IanBoyd:大概
“敏感数据”
“加密密钥”
不是用户产品代码中的实际文本,而是在运行时从用户输入、加载密钥文件等动态获取的。崩溃除外,正如Daniel Chapman早些时候评论的那样,如果它们是实际的文本,那将是一个巨大的安全风险。你完全正确。只需指出一个函数调用,在99.99%的情况下变成no-op可以阻止一个奇怪的崩溃(比如,你有一个单元测试,确保你开始的字符串与你结束的字符串匹配)thx,这正是我所说的:)编译器可以决定优化它吗?也许可以像WinAPI中的SecureZeroMemory那样优化off语句(以及在jedi apilib中实现的语句)来解决这个问题
Var
  S1:String;
  S2:String;
begin
   S1:='Sensitive Data';
   S2:=Crypt(S1,'encryption key');
   UniqueString(S1); // <-- if reference count of S1 is not 1
   ZeroMemory(Pointer(S1), Length(S1)*SizeOf(Char));
   // or better: SecureZeroMemory(Pointer(S1), Length(S1)*SizeOf(Char));
   S1:='';
end;