0

我们如何将 AnsiString 对象归零?例如:

void TesteClass::test()
{
    AnsiString cardNumber = "1234567890123456";
    ..
}

AnsiString 对象被自动销毁,但其内部数据没有被清理,因此内存获取工具可以读取信息。我们需要将此数据归零以避免敏感信息被捕获到内存中。

AnsiString 类有c_str()直接访问内部数据的方法,但不建议这样做:

memset(cardNumber.c_str(), 0, cardNumber.Length());

在对象被销毁之前将 AnsiString 内部数据归零的正确方法是什么?

4

1 回答 1

2

memset()像您所展示的那样使用没有任何问题。以c_str()这种方式使用是正确的(只要不超过Length(), 因为如果为空白c_str(),则返回指向 const 内存的指针):AnsiString

void TesteClass::test()
{
    AnsiString cardNumber = "1234567890123456";
    // ...
    memset(cardNumber.c_str(), 0, cardNumber.Length());
}

既然担心信息泄露,请考虑使用SecureZeroMemory()代替memset()(请参阅SecureZeroMemory 的意义何在?)。

要自动化归零(因此您不必记住这样做),请考虑将AnsiString内部包装为 RAII 样式class/ struct(您不能AnsiString直接派生自,RTL 不允许它),其析构函数执行归零,然后在需要的地方使用那个class/而不是直接使用。structAnsiString

请小心,因为AnsiString使用引用计数数据,所以不要将数据归零,除非您AnsiString是引用数据的唯一实例:

class SaferAnsiString
{
private:
    AnsiString m_Str;

    void CheckZeroNeeded()
    {
        // AnsiString gained a public RefCount() method in C++Builder 2009.
        // In earlier versions, access the reference count manually...
        #ifdef _DELPHI_STRING_UNICODE
        if (m_Str.RefCount() == 1)
        #else
        const void *data = m_Str.data();
        if ((data) && (static_cast<const int*>(data)[-2] == 1))
        #endif
            SecureZeroMemory(m_Str.c_str(), m_Str.Length());
    }

public:
    SaferAnsiString(const AnsiString &src = AnsiString())
        : m_Str(src)
    {
    }

    ~SaferAnsiString()
    {
        CheckZeroNeeded();
    }

    SaferAnsiString& operator=(const AnsiString &rhs)
    {
        CheckZeroNeeded();
        m_Str = rhs;
        return *this;
    }

    operator AnsiString () const { return m_Str; }

    // other methods as needed...
};

void TesteClass::test()
{
    SaferAnsiString cardNumber = "1234567890123456";
    // ...
}
于 2017-05-23T19:58:25.903 回答