在iOS中从内存中清除敏感数据的正确方法是啥?
Posted
技术标签:
【中文标题】在iOS中从内存中清除敏感数据的正确方法是啥?【英文标题】:What is the correct way to clear sensitive data from memory in iOS?在iOS中从内存中清除敏感数据的正确方法是什么? 【发布时间】:2012-04-15 22:13:54 【问题描述】:我想从我的 ios 应用程序的内存中清除敏感数据。 在 Windows 中,我曾经使用 SecureZeroMemory。现在,在 iOS 中,我使用普通的旧 memset,但我有点担心编译器可能会优化它: https://buildsecurityin.us-cert.gov/bsi/articles/knowledge/coding/771-BSI.html
代码sn-p:
NSData *someSensitiveData;
memset((void *)someSensitiveData.bytes, 0, someSensitiveData.length);
【问题讨论】:
【参考方案1】:解释 771-BSI(链接见 OP):
避免编译器优化 memset 调用的一种方法是在 memset 调用之后以强制编译器不优化位置的方式再次访问缓冲区。这可以通过
*(volatile char*)buffer = *(volatile char*)buffer;
在memset()
通话之后。
其实你可以写一个secure_memset()
函数
void* secure_memset(void *v, int c, size_t n)
volatile char *p = v;
while (n--) *p++ = c;
return v;
(代码取自 771-BSI。感谢 Daniel Trebbien 指出之前代码提案可能存在的缺陷。)
为什么volatile
会阻止优化?见https://***.com/a/3604588/220060
更新还请阅读Sensitive Data In Memory,因为如果您的 iOS 系统上有对手,那么在他尝试读取该内存之前,您或多或少已经搞砸了。总之,SecureZeroMemory() 或 secure_memset() 并没有真正的帮助。
【讨论】:
我想也许在 iOS 中有一个相当于 SecureZeroMemory() 的东西。您的解决方案看起来不错,但是“解决方案应该在大多数平台上都有效,但请查阅平台文档以验证以这种方式引用一个字符就足够了。” 我认为这只是小心翼翼地来回蹒跚而行。标准规定,对 volatile 变量的访问不会被优化掉。事实上,一个字符可能是一个硬件端口,而读取访问会触发硬件级别的某些东西。使用 volatile,您可以向编译器声明您比它更了解,并且它甚至不会考虑尝试优化该访问。而且因为该访问依赖于它前面的 memset(),所以 memset() 不会被优化掉。 您的secure_memset
函数可能不够用。根据open-std.org/jtc1/sc22/wg14/www/docs/n1381.pdf 的说法,有一些优化编译器只会将第一个字节归零。
这不是我的。它来自 771-BSI。
也许页面变了?如果你再看一遍,他们有一个循环volatile char *p = v; while (n--) *p++ = c;
【参考方案2】:
问题是 NSData 是不可变的,你无法控制发生的事情。如果缓冲区由您控制,您可以使用 dataWithBytesNoCopy:length: 并且 NSData 将充当包装器。完成后,您可以 memset 缓冲区。
【讨论】:
以上是关于在iOS中从内存中清除敏感数据的正确方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章
为 iOS/Android 应用程序存储敏感数据的最佳方式是啥?