在某些情况下,密码将始终显示为字符串 或其他情况。而且我感到不安,让它无限期地挂在记忆中 (特别是在字符串被Interned的情况下)。 所以在字符串不是的情况下是leats实习生我建议: string pass = Console.ReadLine(); if(string.IsInterned(pass)== null) { 不安全 { 固定(无效* pv =通行证) { char * pb =(char *)pv; for(int i = 0; i< pass.Length; ++ i) pb [ i] =''0''; } } } Console.WriteLine(通过) ; 注意:不需要显式的RuntimeHelpers.OffsetToStringData。 你们对此有何看法? 解决方案 用新值覆盖它有什么问题? pass = new String(); 因为这仍然是同一个变量,我不认为应用程序会挂起旧的 值 - 罪那时他们是不可想象的。对?你是否过度思考这个问题?b $ b或者我错过了什么? " cppdev" < CP ***** @ yahoo.com>在消息中写道 新闻:fc ************************* @ posting.google.co m ... 我想清除敏感信息中的字符串内容,比如密码等等。 它''总是密码在某些时候或其他地方显示为字符串的情况。而且我感到不安,让它无限期地挂在记忆中(特别是在字符串是Interned的情况下)。 所以在字符串未被实习的情况下,我建议: string pass = Console.ReadLine(); if(string.IsInterned(pass)== null) {不安全 {固定( void * pv = pass) {*> char * pb =(char *)pv; for(int i = 0; i< pass.Length; ++ i) pb [i] =''0''; } } } Console.WriteLine(传递); 注意:显式的RuntimeHelpers。不需要OffsetToStringData。 您对此有何看法? " Frank Drebin <无***** @ imsickofspam.com>在留言中写道 news:bJ ********************** @ newssvr28.news.prodi gy.com ... 用新值覆盖它有什么问题? pass = new String(); 那是行不通的。你所做的只是创建一个新的 String对象并替换指针。旧字符串 对象仍在内存中,标记为垃圾回收。 但是,垃圾收集器可能无法运行一对 分钟在发生这种情况之前,一个饼干可能会扫描并看到 。 字符串是不可变的,期间。 无法在字符串创建后替换字符串中的内容。 唯一的选择可能是使用值类型 仅在方法的生命周期内将其保留在堆栈中 使用它。您可以编写自己的基本 字符串类,它与char []一起使用(也是 a值类型)。 这样就没有分配堆内存,因此很难追踪到。但是,当密码在堆栈上可见时,总有几秒钟就会有。也许用于处理 char []的值类型中的一些聪明(和丑陋) 编码会在预定义的 空格中插入随机字符抛弃一个随意的观察者。 因为这仍然是同一个变量,我不认为应用程序挂起到旧值 - 因为它们在那时是不可想象的。对?你是否过度思考这个问题?或者我错过了什么? 内存尚未被覆盖。堆内存仍然是仍然分配,CLR仍然有对这个 内存插槽的引用。该参考文件将被标记为垃圾 收集并在下一个可用的 GC插槽中收集/免费提供。但是,目前尚不清楚.NET是否会将内存零容纳出来,或者只是留在那里被覆盖 之后。我的猜测是它不会将内存清零。 或者,您可能会在C#中使用不安全的代码来获取 a内存块,其中你工作时存储密码 (当然你必须使用旧式的 C字符串逻辑很难看)然后把它归零 完成后你自己。 -c " cppdev" < CP ***** @ yahoo.com>在消息中写道新闻:fc ************************* @ posting.google.co m ... 大家好! 我想从密码等敏感信息中清除字符串内容。 这总是一个案例该密码将在某些时候显示为字符串或其他。并且我感到不安,让它无限期地挂在内存中(特别是在字符串被Interned的情况下)。 所以在字符串未被实习的情况下,我建议: string pass = Console.ReadLine(); if(string.IsInterned(pass)== null) {不安全 {固定( void * pv = pass) {*> char * pb =(char *)pv; for(int i = 0; i< pass.Length; ++ i) pb [i] =''0''; } } } Console.WriteLine(传递); 注意:显式的RuntimeHelpers。不需要OffsetToStringData。 您对此有何看法? " Frank Drebin" <无***** @ imsickofspam.com>在消息中写道 新闻:KC ********************** @ newssvr28.news.prodi gy.com ... 理解.. 如果你这样做: pass = new String(); pass =" mypassword"; pass =" ; 你是否建议同样的事情发生?在上面的示例中,有pass的当前版本。和两个旧版本的标记为gc?由于内存已经分配 - 为什么它只是改变实际的内存数据? 通过变量只是一个参考。 新 .NET中的operator返回一个REFERENCE到堆上新创建的对象。 在C ++中,例子是: String * pass = new System :: String(" 1"); pass = new System :: String(" 2,mypassword"); pass = new System :: String(" 3,"); 所以你看,字符串1和2仍在那里,你只是 摆脱了你的参考。 [转述,这不一定是100%准确] [是的,我知道.NET不做引用计数,但 这只是为了说明] 在幕后,当调用新运算符时, 它在堆上分配内存并创建 a新的Reference对象来存储指针。 它有一些类型的Referers集合和它 给你一个Referers令牌。 所以通过值实际上只包含一个 referer令牌到实际参考。 当变量/令牌超出范围时,或者你 为你的变量/令牌指定null,.NET将 删除你的令牌。 这很方便因为.NET可以移动内存 随时随地更新 实际指针而不会影响你的代码 。 当没有更多的引用时,.NET标记 垃圾收集指针。 所以你看,只因为你不再拥有 a指向字符串1和2,它并不意味着 没有人指向它。 1,2,和3所有都是在堆上的不同 部分中的唯一对象并且通过在所有3个案例中都有一个完全 不同的值。 仍然分配1和2的内存, 甚至收集垃圾之后,它可能会实际上没有被清零或覆盖,直到 a稍晚。 其次,是什么密码所需的最终形式以及为什么不能尽快将其隐藏起来。例如,如果密码是来自文本框的 - sha1将密码哈希到字符串中 - 那么你不需要b $ b来担心它.. 不幸的是,这是一个非常复杂的问题。 TextBox 有一个String类型的Text属性,它有一个 密码的副本。 当你得到一个参考从中生成 哈希的字符串,可能会创建另一个副本。 最终可能会有1-3份副本内存中的字符串:( < snip> " Chad Myers" < cm **** @ N0.SP.4M.austin.rr.com>在消息中写道新闻:8r ******************* @ twister.austin.rr.com .. Frank Drebin< no ***** @ imsickofspam.com>写在消息中新闻:bJ **********************@newssvr28.news.prodi gy.com ... 什么是麻烦只是用新值覆盖它? pass = new String(); 那是行不通的。你所做的只是创造一个新的 String对象并替换指针。旧的字符串对象仍然在内存中,标记为垃圾收集。然而,垃圾收集器可能无法运行几分钟,并且有可能一个黑客可以在此之前扫描并查看它发生。 字符串是不可变的,期间。创建字符串后无法替换字符串中的内容。 唯一的选择可能是使用一种值类型,仅将其保留在堆栈中其使用方法的生命。您可以编写自己的基本字符串类,它与char [](也是值类型)一起使用。 这样就不会分配堆内存并且 char []的Value类型中的一些聪明(和丑陋)编码会在预定义的空格中插入随机字符以抛弃一个不经意的观察者。 由于这仍然是同一个变量,我不认为应用程序在 上挂起到旧的值 - 因为它们在那时是不可想象的。对?是 你是否过度思考问题?或者我错过了什么? 内存尚未被覆盖。堆内存仍然已分配,CLR仍然具有对该内存插槽的引用。该参考文件将被标记为垃圾收集,并在下一个可用的GC插槽中收集/免费提供。然而,目前还不清楚.NET是否会将内存归零,或者只是将其留在那里以便稍后覆盖。我的猜测是它不会将内存清零。 或者,您可能会在C#中使用不安全的代码来获取存储密码的内存块当你工作的时候(当然你必须使用丑陋的旧式的C字符串逻辑),然后在你完成时把它归零。 -c " cppdev" < CP ***** @ yahoo.com>在消息中写道新闻:fc ************************* @ posting.google.co m ... > ;大家好!> >我想从敏感信息中清除字符串内容>如密码等。> >密码将在某个点>处显示为字符串。或其他。我感到不安,把它挂在记忆中 无限期地> (特别是在字符串被Interned的情况下)。> >因此,对于字符串未被实习的情况,我建议:> > string pass = Console.ReadLine(); > if(string.IsInterned(pass)== null)> {>不安全> {> fixed(void * pv = pass)> {> char * pb =(char *)pv; > for(int i = 0; i< pass.Length; ++ i)> pb [i] =''0''; > } > } > } > Console.WriteLine(pass); > >注意:不需要显式的RuntimeHelpers.OffsetToStringData。> >您对此有何看法? Hi All! I want to clear the string contents from sensitive informationsuch as passwords, and etc. It''s always a case that password will appear as string at some pointor another. And i feel uneasy leaving it hanging in memory indefinitely(especially in case when string is Interned). So at leats for the case when string is not interned i propose: string pass = Console.ReadLine();if (string.IsInterned(pass) == null){unsafe{fixed(void* pv = pass){char* pb = (char*)pv;for(int i =0; i<pass.Length; ++i)pb[i] = ''0'';}}}Console.WriteLine(pass); Note: explicit RuntimeHelpers.OffsetToStringData is not needed. What do you all think about this? 解决方案 What''s the trouble with just overwriting it with a new value? pass = new String(); Since this is still the same variable, I don''t think the app hangs on to oldvalues - since they are unretreivable at that point. Right? Are youoverthinking the problem? Or am I missing something? "cppdev" <cp*****@yahoo.com> wrote in messagenews:fc*************************@posting.google.co m... Hi All! I want to clear the string contents from sensitive information such as passwords, and etc. It''s always a case that password will appear as string at some point or another. And i feel uneasy leaving it hanging in memory indefinitely (especially in case when string is Interned). So at leats for the case when string is not interned i propose: string pass = Console.ReadLine(); if (string.IsInterned(pass) == null) { unsafe { fixed(void* pv = pass) { char* pb = (char*)pv; for(int i =0; i<pass.Length; ++i) pb[i] = ''0''; } } } Console.WriteLine(pass); Note: explicit RuntimeHelpers.OffsetToStringData is not needed. What do you all think about this?"Frank Drebin" <no*****@imsickofspam.com> wrote in messagenews:bJ**********************@newssvr28.news.prodi gy.com... What''s the trouble with just overwriting it with a new value? pass = new String();That doesn''t work. All you''re doing is creating a newString object and replacing the pointer. The old stringobject is still in memory, flagged for garbage collection.However, the garbage collector may not run for a coupleminutes and it''s possible a cracker could scan and seeit before that happens. Strings are immutable, period. There is no way toreplace the contents in a string once it is created. The only option might be to use a value type whichkeeps it on the stack only for the life of the methodin which its used. You might write your own basicstring class which works with char[] (which is alsoa value type). That way no heap memory is ever allocated andtherefore harder to track down. However, there isalways that few seconds when the password isvisible on the stack. Perhaps some clever (and ugly)coding in the Value type for working with thechar[] would insert random characters at predefinedspaces to throw off a casual observer. Since this is still the same variable, I don''t think the app hangs onto old values - since they are unretreivable at that point. Right? Are you overthinking the problem? Or am I missing something?The memory has not yet been overwritten. The heap memory isstill allocated and the CLR still has a reference to thatmemory slot. The reference will be flagged for garbagecollection and collected/free''d at the next availableGC slot. However, it''s not clear whether .NET will zero-outthe memory, or just leave it there to be overwrittenlater. My guess is that it DOES NOT zero-out the memory. Alternatively, you might use unsafe code in C# to geta block of memory in which to store the passwordwhile you work with (of course you have to use old-styleC string logic which is ugly) and then zero it outyourself when you''re done. -c "cppdev" <cp*****@yahoo.com> wrote in message news:fc*************************@posting.google.co m... Hi All! I want to clear the string contents from sensitive information such as passwords, and etc. It''s always a case that password will appear as string at some point or another. And i feel uneasy leaving it hanging in memoryindefinitely (especially in case when string is Interned). So at leats for the case when string is not interned i propose: string pass = Console.ReadLine(); if (string.IsInterned(pass) == null) { unsafe { fixed(void* pv = pass) { char* pb = (char*)pv; for(int i =0; i<pass.Length; ++i) pb[i] = ''0''; } } } Console.WriteLine(pass); Note: explicit RuntimeHelpers.OffsetToStringData is not needed. What do you all think about this?"Frank Drebin" <no*****@imsickofspam.com> wrote in messagenews:KC**********************@newssvr28.news.prodi gy.com... Understood.. And if you did this: pass = new String(); pass = "mypassword"; pass = " "; Are you suggesting the same thing happens? In that in the aboveexample, there is the current version of "pass" and two old versions that areflagged for gc? Since the memory is already allocated - why wouldn''t it justchange the actual memory data??The "pass" variable is just a reference. The "new" operator in .NET returns a REFERENCE to thenewly-created object on the heap. In C++, the example would be: String* pass = new System::String("1");pass = new System::String("2, mypassword");pass = new System::String("3, "); So you see, string 1 and 2 are still there, you justgot rid of your reference them. [paraphrased, this isn''t necessarily 100% accurate][yes, I know .NET doesn''t do reference counting, butthis is just for illustration]Behind the scenes, when the new operator is called,it allocates the memory on the heap and createsa new Reference object to store the pointer in. It has some type of collection of Referers and itgives you a Referers token. So the "pass" value actually just contains areferer token to the actual reference. When the variable/token goes out of scope, or youassign null to your variable/token, .NET willremove your token. This is handy because .NET can move the memoryaround whenever it wants and updates theactual pointer without affecting your codein any way. When there are no more referers, .NET flagsthe pointer for garbage collection. So you see, just because you no longer havea pointer to Strings 1 and 2, it doesn''t meanno one has a pointer to it. 1, 2, and 3 all are unique objects in differentparts onthe heap and "pass" has a completelydifferent value in all 3 cases. The memory of 1 and 2 is still allocated,and even after it''s garbage collected, it mightnot actually get zeroed out or overwritten untila little later. Secondly, what is the ultimate form you need for the password and whynot get it coverted as soon as possible. For example, if the password iscoming from a textbox - sha1 hash the password into a string - then you don''thave to worry about it..Unfortunately, this is a very complicated problem. TextBoxhas a Text property of type String which has a copy of thepassword. When you get a ref of the string from which to generatethe hash, it''s possible that another copy might get created. You might end up with 1-3 copies of the string in memory :( <snip> -c "Chad Myers" <cm****@N0.SP.4M.austin.rr.com> wrote in message news:8r*******************@twister.austin.rr.com.. . "Frank Drebin" <no*****@imsickofspam.com> wrote in message news:bJ**********************@newssvr28.news.prodi gy.com... What''s the trouble with just overwriting it with a new value? pass = new String(); That doesn''t work. All you''re doing is creating a new String object and replacing the pointer. The old string object is still in memory, flagged for garbage collection. However, the garbage collector may not run for a couple minutes and it''s possible a cracker could scan and see it before that happens. Strings are immutable, period. There is no way to replace the contents in a string once it is created. The only option might be to use a value type which keeps it on the stack only for the life of the method in which its used. You might write your own basic string class which works with char[] (which is also a value type). That way no heap memory is ever allocated and therefore harder to track down. However, there is always that few seconds when the password is visible on the stack. Perhaps some clever (and ugly) coding in the Value type for working with the char[] would insert random characters at predefined spaces to throw off a casual observer. Since this is still the same variable, I don''t think the app hangson to old values - since they are unretreivable at that point. Right? Areyou overthinking the problem? Or am I missing something? The memory has not yet been overwritten. The heap memory is still allocated and the CLR still has a reference to that memory slot. The reference will be flagged for garbage collection and collected/free''d at the next available GC slot. However, it''s not clear whether .NET will zero-out the memory, or just leave it there to be overwritten later. My guess is that it DOES NOT zero-out the memory. Alternatively, you might use unsafe code in C# to get a block of memory in which to store the password while you work with (of course you have to use old-style C string logic which is ugly) and then zero it out yourself when you''re done. -c "cppdev" <cp*****@yahoo.com> wrote in message news:fc*************************@posting.google.co m... > Hi All! > > I want to clear the string contents from sensitive information > such as passwords, and etc. > > It''s always a case that password will appear as string at somepoint > or another. And i feel uneasy leaving it hanging in memory indefinitely > (especially in case when string is Interned). > > So at leats for the case when string is not interned i propose: > > string pass = Console.ReadLine(); > if (string.IsInterned(pass) == null) > { > unsafe > { > fixed(void* pv = pass) > { > char* pb = (char*)pv; > for(int i =0; i<pass.Length; ++i) > pb[i] = ''0''; > } > } > } > Console.WriteLine(pass); > > Note: explicit RuntimeHelpers.OffsetToStringData is not needed. > > What do you all think about this? 这篇关于我想清楚“不可变”的字符串内容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 10-23 14:10