2010-09-24 25 views
13

Câu hỏi này theo một đề xuất được thực hiện bởi @sharptooth trong this related question.Làm thế nào để viết một lớp mật khẩu an toàn?

Có thể chỉnh sửa std::string để mật khẩu an toàn không?

Nếu không, các hướng dẫn để viết một lớp xử lý mật khẩu là gì (vì vậy một lớp cần chú ý nhiều về những gì nó ghi vào bộ nhớ và xóa nó trước khi hủy)?

+1

1) sử dụng std: wstring, 2) đẩy 0x2022 thay vì ký hiệu mật khẩu: o) Nghiêm túc, nếu bạn lo sợ rằng quá trình khác sẽ đánh cắp thứ gì đó từ bộ nhớ của bạn, hãy thêm/xóa một số mặt nạ vào nó (xor?) – alxx

+0

@alxx : Làm thế nào sẽ sử dụng 'std :: wstring' thay vì' std :: string' được an toàn hơn?! Tui bỏ lỡ điều gì vậy ? – ereOn

+1

0x2022 là ký hiệu dấu đầu dòng. Hiểu rồi? :) – alxx

Trả lời

19

Vâng, đầu tiên xác định một cấp phát tùy chỉnh:

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); 
    } 
}; 

cấp phát này Zeros bộ nhớ trước khi deallocating. Bây giờ bạn đã gõ:

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

Tuy nhiên, có thể sử dụng tối ưu hóa chuỗi nhỏ và lưu trữ một số dữ liệu bên trong mà không có phân bổ động. Vì vậy, bạn phải dứt khoát rõ ràng nó trên tiêu huỷ hoặc phân bổ trên heap với cấp phát tùy chỉnh của chúng tôi:

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

} 

Điều này đảm bảo rằng tất cả các dữ liệu được zeroed trước deallocation, bao gồm kích thước của chuỗi, ví dụ.

+5

Không sử dụng 'std :: fill_n', sử dụng một cái gì đó như' SecureZeroMemory() '(http://msdn.microsoft.com/en-us/library/aa366877(VS.85).aspx) - với' std :: fill_n' trình biên dịch có thể tối ưu hóa việc xóa đi. – sharptooth

+0

Cũng có một tinh chỉnh để buộc 'std :: string' xóa không gian khi mã gọi làm cho chuỗi bị rút ngắn - ví dụ loại bỏ phần tử N đầu tiên và do đó đuôi được dịch chuyển" trái "và để lại ký tự" ở bên phải "? – sharptooth

+1

@sharptooth SecureZeroMemory không phải là tiêu chuẩn và dễ bay hơi ngăn tối ưu hóa. Có, nếu không có hệ thống gọi một số dữ liệu có thể vẫn còn trong bộ nhớ trước khi CPU xóa bộ nhớ cache. – ybungalobill

Các vấn đề liên quan