Nullify QString数据字节

Nik*_*kin 6 c++ qstring qt

我用QStrings来存储密码.如果更准确,我使用QStrings从GUI获取密码.关键是在密码使用/设备之后我需要QString用密码使内部s数据字节无效(零)以完全从内存中消除它.

这是我的调查:

  • QString破坏它的数据保留在内存中nonzeroed;
  • 当我尝试修改QString以使用零来实现它时,它会触发写时复制习惯用法并为修改后的数据变量分配新内存.旧数据保持不变.即使我使用QString::data()方法也是如此.不太确定为什么 - 可能是因为它不是原始的char *但是QChar *;
  • QString::clear(),= ""实际上与上述COW相同.

问:如何实施正确的QString清理以防止密码泄露?

KjM*_*Mag 7

我有两种绕过写时复制的可能方法。我已经尝试过它们并且它们似乎有效 - 没有使用 Qt Creator 的内存查看器,但是在我的代码中使用的隐式共享 QStrings 都指向了相同的归零数据。

使用 constData()

正如QString::data() 方法Qt 文档中所写:

对于只读访问, constData() 更快,因为它永远不会导致发生深拷贝。

所以可能的解决方案如下所示:

QString str = "password";
QString str2 = str;
QChar* chars = const_cast<QChar*>(str.constData());
for (int i = 0; i < str.length(); ++i)
    chars[i] = '0';
// str and str2 are now both zeroed
Run Code Online (Sandbox Code Playgroud)

这是一个合法的使用,const_cast因为底层数据不是真的const,所以这里没有未定义的行为。

使用迭代器

用于隐式共享Qt 文档

隐式共享类可以控制其内部数据。在任何修改其数据的成员函数中,它会在修改数据之前自动分离。但是,请注意容器迭代器的特殊情况;请参阅隐式共享迭代器问题。

因此,让我们转到描述此迭代器问题的部分:

隐式共享对 STL 样式的迭代器有另一个后果:当迭代器在该容器上处于活动状态时,您应该避免复制该容器。迭代器指向一个内部结构,如果你复制一个容器,你应该非常小心你的迭代器。例如:

QVector<int> a, b;
a.resize(100000); // make a big vector filled with 0.

QVector<int>::iterator i = a.begin();
// WRONG way of using the iterator i:
b = a;
/*
    Now we should be careful with iterator i since it will point to shared data
    If we do *i = 4 then we would change the shared instance (both vectors)
    The behavior differs from STL containers. Avoid doing such things in Qt.
*/

a[0] = 5;
/*
    Container a is now detached from the shared data,
    and even though i was an iterator from the container a, it now works as an iterator in b.
*/
Run Code Online (Sandbox Code Playgroud)

我的理解是,根据上述文档片段,您应该能够利用迭代器的这种“错误用法”来使用迭代器操作原始字符串,因为它们不会触发写时复制。在任何复制发生之前“拦截”begin()和很重要end()

QString str = "password";
QString::iterator itr = str.begin();
QString::iterator nd = str.end();
QString str2 = str;

while (itr != nd)
{
    *itr = '0';
    ++itr;
} // str and str2 still point to the same data and are both zeroed
Run Code Online (Sandbox Code Playgroud)