敏感数据:NSString VS NSMutableString (iPhone)
我有一些敏感数据想在使用后直接清除。目前,敏感数据都是NSString的形式。根据我的理解,NSString 是不可变的,这意味着我无法真正清除数据。不过,NSMutableString 似乎更合适,因为它是可变的,并且具有诸如replaceCharactersInRange 和deleteCharactersInRange 之类的方法。我不了解实现细节,所以我想知道 NSMutableString 是否能满足我的目的?
I have some sensitive data I want to clear directly after use. Currently, the sensitive data is in the form of NSString. NSString is in my understanding immutable, meaning that I can't really clear the data. NSMutableString seems more appropriate, though, as it is mutable and has methods like replaceCharactersInRange and deleteCharactersInRange. I have no knowledge of the implementation details so I wonder if NSMutableString would serve my purpose?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我担心 NSMutableString 会尝试优化并将字符串保留在内存中。如果您想要更多控制,请尝试分配自己的内存,然后用它创建一个 NSString。如果这样做,您可以在释放内存之前覆盖它。
I would be afraid NSMutableString would try to optimize and leave the string in memory. If you want more control try allocating your own memory then create an NSString with it. If you do that you can overwrite the memory before you release it.
您需要使用 memset 函数用零擦除 c 指针,但是编译器可以优化 memset 调用,请参阅 从 iOS 内存中清除敏感数据的正确方法是什么?
所以代码可能是这样的:
但要小心清除 NSString 的底层 c 指针。例如,在设备上,如果字符串包含单词“password”,则底层 c 指针只会重用或指向系统使用的相同地址,并且尝试擦除该内存区域将会崩溃。
为了安全起见,您可能需要使用 char 数组而不是 char 指针来存储敏感字符串并在之后擦除它们,而无需将其放入 NSString 对象中。
You need to wipe the c pointer with zeros with a memset function however a memset call can be optimized out by the compiler, see What is the correct way to clear sensitive data from memory in iOS?
So the code could be something like this:
But be careful clearing the underlying c pointer of an NSString. On a device for example, if the string contains the word "password", the underlying c pointer just reuses or points to the same address as used by the system and you will crash by trying to wipe this area of memory.
To be safe you may want to use a char array, not the char pointer, to store your sensitive strings and wipe them after without ever putting it into an NSString object.
如果攻击者可以读取内存的内容,那么您就完蛋了。
-release
字符串并完成。无法知道您是否已删除各种缓存中字符串的任何可能副本(例如是否将其绘制到屏幕等)。您可能有更重要的安全问题需要担心。
If an attacker can read the contents of memory, you are beyond hosed.
-release
the string and be done with it. There's no way to know if you've deleted any possible copies of the string in various caches (such as if you draw it to screen, etc).You probably have much more significant security issues to worry about.
从 iOS9 开始,从下面的代码片段获取的 NSString 内部指针已变为只读,并在尝试设置字节时生成错误访问。
使用 NSMutableString 是可能的,但是如果你有另一个 NSString 源,比如来自文本字段,那么该源仍然在内存中,你仍然不走运。
如果您要创建一个新的 NSString,最好的方法是使用底层字节数组实现您自己的 String 类。提供一种使用底层字节数组作为内部指针来创建 NSString 副本的方法:
As of iOS9, inner pointer of NSString obtained from the snippet below has become read-only and generates bad access when trying to set the bytes.
It is possible with NSMutableString but then if you have another NSString source, say from a textfield, that source will still be in memory and you're still out of luck.
If you are creating a new NSString, The best way is implement your own String class with underlying byte array. Provide a method to create NSString copies using the underlying byte array as the inner pointer.: