Вопрос или проблема
С точки зрения безопасности лучше обнулить пароль, как только он больше не используется программой.
Иными словами, я хотел бы иметь некую безопасную строку вместо std::string
, которая обнуляла бы область памяти, где хранилась старая C-строка, при разрушении или при присвоении ей нового значения.
Реализовать такую строку самостоятельно не проблема, но это займет довольно много времени, чтобы реализовать все обширные функции std::string
, которые я хотел бы иметь.
Существуют ли готовые решения для этого?
Ранее я задавал этот вопрос на Stack Overflow.
Я нашел решение в этом ответе.
CryptoPP::AllocatorWithCleanup
— это пользовательский аллокатор, предоставляемый библиотекой Crypto++. Он обнуляет выделенную память при деалокации.
Деалокация происходит, когда строка уничтожается или когда ее буфер переполняется, в результате чего создается новый буфер большего размера, а старый буфер освобождается (могут быть и другие сценарии).
Тем не менее, это может не срабатывать при использовании операций clear()
или resize()
.
Мое решение, основанное на этом ответе:
SecureString.h
#pragma once
#include <string>
#include <cryptopp/secblock.h>
template <typename CharType, typename TraitsType = std::char_traits<CharType>>
using BasicSecureString = std::basic_string<CharType, TraitsType, CryptoPP::AllocatorWithCleanup<CharType>>;
using SecureString = BasicSecureString<char>;
CMakeLists.txt
target_link_libraries(${EXECUTABLE_NAME} cryptopp)
Как установить библиотеку на дистрибутивах на базе Ubuntu:
sudo apt install libcrypto++-dev
Ответ или решение
Использование безопасной строки для хранения паролей в C++ — важный аспект, касающийся защиты данных. С точки зрения безопасности, действительно рекомендуется обнулять память, содержащую пароли, после того, как они перестали быть необходимыми программе.
Как вы правильно отметили, стандартные строки (std::string
) не обеспечивают этой функциональности, так как их деструктивные методы не гарантируют, что память будет обнулена при уничтожении объекта. Вместо этого можно использовать специализированные решения.
Одно из доступных решений — это использование библиотеки Crypto++ и ее функциональности для создания безопасных строк с помощью специального аллокатора, который обнуляет память при деаллокации. Вот как можно реализовать аналог std::string
, который использует такой аллокатор.
Реализация SecureString
- Создайте заголовочный файл
SecureString.h
:
#pragma once
#include <string>
#include <cryptopp/secblock.h>
template <typename CharType, typename TraitsType = std::char_traits<CharType>>
using BasicSecureString = std::basic_string<CharType, TraitsType, CryptoPP::AllocatorWithCleanup<CharType>>;
using SecureString = BasicSecureString<char>;
Таким образом, SecureString
будет работать как std::string
, но с обеспечением очистки памяти.
- Настройка CMake:
Вам нужно добавить библиотеку Crypto++ в зависимости вашего проекта. В файле CMakeLists.txt
это делается так:
target_link_libraries(${EXECUTABLE_NAME} cryptopp)
- Установка библиотеки Crypto++ в Ubuntu:
На Ubuntu-based системах вы можете установить библиотеку Crypto++ с помощью следующей команды:
sudo apt install libcrypto++-dev
Обратите внимание на несколько моментов
-
Деаллокация памяти: С использованием
CryptoPP::AllocatorWithCleanup
, память будет обнулена при деаллокации, что происходит, когда строка уничтожается или когда происходит переполнение буфера. Однако это не произойдет при использовании методовclear()
илиresize()
, поскольку они могут не затрагивать всю память, выделенную под строку. -
Эквивалентные операции: Вам может потребоваться реализовать дополнительные функции для обработки строк, как это делается в
std::string
, включая копирование, перемещение и присваивание, особенно если вы планируете использоватьSecureString
в контексте, где важна производительность. -
Угрозы безопасности: Важно помнить, что, несмотря на использование безопасных строк, всегда нужно быть внимательным к потенциальным угрозам, связанным с безопасностью. Например, всегда следует тщательно следить за тем, как пароли и другие конфиденциальные данные хранятся и обрабатываются в памяти.
Используя SecureString
в своих проектах, вы сможете быстрее разработать безопасное приложение, минимизировав риски, связанные с несанкционированным доступом к паролям и конфиденциальной информации.