在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 应用程序存储敏感数据的最佳方式是啥?

在 Swift 中从 json 文件中读取数据的正确方法是啥?

天生对数字不敏感的人,如何提升对数据的敏感度?

c# 并从内存中删除敏感数据和所有垃圾收集副本

从内存中删除敏感信息

在上下文(非)敏感分析中,“上下文”到底是啥意思?