代码之家  ›  专栏  ›  技术社区  ›  ereOn

如何编写密码安全类?

  •  14
  • ereOn  · 技术社区  · 14 年前

    这个问题是根据@sharptooth在 this related question .

    罐头 std::string 被调整到密码安全的程度?

    如果不是,那么编写密码处理类的指导原则是什么(这样一个类会非常注意它向内存中写入的内容,并在销毁之前清除它)?

    1 回复  |  直到 14 年前
        1
  •  20
  •   Yakov Galka    14 年前

    是,首先定义自定义分配器:

    template <class T> class SecureAllocator : public std::allocator<T>
    {
    public:
        template<class U> struct rebind { typedef SecureAllocator<U> other; };
    
        SecureAllocator() throw() {}
        SecureAllocator(const SecureAllocator&) throw() {}
        template <class U> SecureAllocator(const SecureAllocator<U>&) throw() {}
    
        void deallocate(pointer p, size_type n)
        {
            std::fill_n((volatile char*)p, n*sizeof(T), 0);
            std::allocator<T>::deallocate(p, n);
        }
    };
    

    这个分配器在释放前将内存归零。现在您typedef:

    typedef std::basic_string<char, std::char_traits<char>, SecureAllocator<char>> SecureString;
    

    然而,还有一个小问题,STD::String可以使用小字符串优化,并在内部存储一些数据,而不进行动态分配。因此,您必须在销毁时显式清除它,或者使用自定义分配器在堆上进行分配:

    int main(int, char**)
    {
        using boost::shared_ptr;
        using boost::allocate_shared;
        shared_ptr<SecureString> str = allocate_shared<SecureString>(SecureAllocator<SecureString>(), "aaa");
    
    }
    

    这样可以保证所有数据在释放之前都归零, 包括 例如,字符串的大小。