Дилемма безопасности (шифрования) - PullRequest
7 голосов
/ 07 мая 2009

У меня есть внутреннее клиентское приложение WPF, которое обращается к базе данных.

Приложение является центральным ресурсом для группы поддержки и, таким образом, содержит информацию об удаленном доступе / входе в систему для клиентов. На данный момент эта база данных недоступна через веб-интерфейс и т. Д., Но однажды, вероятно, будет.

Информация об удаленном доступе включает имя пользователя и пароли для сетей клиента, чтобы мы могли удаленно поддерживать программные приложения нашего клиента. Мне нужно сохранить имена пользователей и пароли в базе данных и предоставить консультантам по поддержке доступ к ним, чтобы они могли войти в систему клиента и затем оказать поддержку. Надеюсь, что это имеет смысл.

Таким образом, дилемма заключается в том, что я не хочу хранить имена пользователей и пароли в открытом виде в базе данных, чтобы гарантировать, что, если БД когда-либо была скомпрометирована, я не предоставляю доступ к сетям наших клиентов для тех, кто получает базу данных.

Я рассмотрел двустороннее шифрование паролей, но, как говорится, двустороннее шифрование не сильно отличается от открытого текста, как если бы вы могли его расшифровать, так что злоумышленник может ... в конце концов. Проблема здесь в том, что я настроил метод для использования соли и пароля, которые хранятся в приложении, я использовал соль, которая хранится в БД, но у всех есть свои слабые стороны, т.е. если приложение было отражено, оно предоставляет соли и т. д.

Как я могу защитить имена пользователей и пароли в моей базе данных, и в то же время предоставить моим консультантам по поддержке возможность просматривать информацию в приложении, чтобы они могли использовать ее для входа в систему?

Это, очевидно, отличается от хранения пользовательских паролей, поскольку это один из способов, потому что мне не нужно знать, что это такое. Но мне нужно знать, что представляют собой пароли удаленного доступа клиента, поскольку мы должны вводить их во время удаленного взаимодействия с ними.

У кого-нибудь есть какие-то теории о том, что будет лучшим подходом здесь?

обновление Функция, которую я пытаюсь создать, предназначена для нашего приложения CRM, в котором будут храниться детали удаленного доступа для клиента. Система CRM обеспечивает функциональность отслеживания вызовов / проблем, и в ходе изучения проблемы консультант службы поддержки должен будет выполнить удаленное подключение. Затем они просматривают данные удаленного доступа клиента и устанавливают соединение

Ответы [ 7 ]

6 голосов
/ 07 мая 2009

Есть несколько способов сделать это; Лучшее решение будет зависеть от того, как ваша группа поддержки обращается к сайтам клиентов, сколько участников входит в группу поддержки и от архитектуры вашего приложения.

Лучший способ сделать что-то подобное - использовать что-то вроде Kerberos. Таким образом, членам группы поддержки не нужно доверять пароли клиентов - пароли, которые они могут записать и использовать позже для атаки на клиентов. Служба поддержки может мгновенно аннулировать доступ участника без каких-либо действий со стороны клиента.

Однако я предполагаю, что это более опасная система, в которой члены команды получают пароль для доступа к клиентским системам через удаленный рабочий стол, SSH или что-то в этом роде. В этом случае возникает большая ответственность, когда клиентские пароли раскрываются членам команды.

Лично я бы не принял такой риск. Дело не в том, что я чувствую, что могу доверять своей команде, а в том, что я не могу доверять своим клиентам. Если что-то происходит на их сайте (или даже если они просто делают вид, что что-то произошло), вдруг я подозреваю. Я бы предпочел разработать систему, в которой никто не мог бы получить доступ к системам клиентов, действующим в одиночку. Это защищает клиента от плохого яблока в моей команде и защищает меня от ложных обвинений.

В любом случае, одним из подходов будет генерирование ключей для каждого члена команды. Это могут быть симметричные ключи шифрования на основе пароля, но тогда некоторый секретный ключ должен храниться централизованно. Лучше было бы использовать асимметричный алгоритм, такой как RSA. Тогда только открытые ключи членов команды хранятся централизованно.

Когда новый пароль получен от клиента, зашифруйте его открытым ключом каждого члена команды, которому требуется копия. Этот зашифрованный пароль может быть сохранен в базе данных и предоставлен члену команды каждый раз, когда он запрашивает его, или он может быть активно выдан членам команды для их сохранения. В любом случае, когда это необходимо, пароль расшифровывается с помощью закрытого ключа, который хранится у члена команды (в хранилище ключей, зашифрованном с помощью выбранного пароля).

В этом есть и недостатки. Повторяя пункт выше, члены команды получают доступ к паролю клиентов. Они достойны этого доверия? Что если клиент имеет нарушение безопасности, не связанное с этой системой, но хочет свалить вину на кого-то? Во-вторых, хотя на сервере не хранятся ключи дешифрования, необходимо установить доверие для открытого ключа каждого члена команды. В противном случае злоумышленник может вставить свой собственный мошеннический открытый ключ в коллекцию и получить пароли, которые он может расшифровать.

4 голосов
/ 08 мая 2009

Аналогичная ситуация возникает в нашей компании, где администраторы баз данных хотят поддерживать между собой пул учетных данных.

Я изначально собирался опубликовать эту идею, но Эриксон побил меня ею . Однако, возможно, стоит написать какой-нибудь псевдокод, чтобы уточнить, поэтому я полагаю, что мое время, отвечающее на вопрос, не напрасно тратится ...

Вещи, которые вам понадобятся:

Прежде всего, давайте настроим схему базы данных. Эти таблицы будут продемонстрированы в ближайшее время.

CREATE TABLE users (
  user_id               INTEGER,
  authentication_hash   BINARY,
  authentication_salt   BINARY,
  public_key            BINARY,
  encrypted_private_key BINARY,
  decryption_key_salt   BINARY,
  PRIMARY KEY(user_id)
)

CREATE TABLE secrets (
    secret_id INTEGER,
    -- WHATEVER COLUMNS YOU REQUIRE TO ACCURATELY MODEL YOUR PASSWORDS (CLIENT INFO, ETC)
    PRIMARY KEY(secret_id)
)

CREATE TABLE granted_secrets (
  secret_id      INTEGER,
  recipient_id   INTEGER,
  encrypted_data BINARY,
  PRIMARY KEY(secret_id, recipient_id),
  FOREIGN KEY(secret_id) REFERENCES secrets(secret_id)
  FOREIGN KEY(recipient_id) REFERENCES users(user_id)
)

Прежде чем пользователь сможет начать использовать эту систему, он должен быть зарегистрирован.

function register_user(user_id, user_password) {
    authentication_salt = generate_random_salt()
    authentication_hash = hash(authentication_salt, user_password);

    (public_key, private_key) = asymmetric_cipher_generate_random_key_pair();

    decryption_key_salt = generate_random_salt()
    decryption_key = derive_key(decryption_key_salt, user_password)
    encrypted_private_key = symmetric_cipher_encrypt(
        input => private_key,
        key   => decryption_key
    )

    // IMPORTANT: The decryption_key_hash is never stored

    execute("INSERT INTO users (user_id, authentication_hash, authentication_salt, public_key, encrypted_private_key, decryption_key_salt) VALUES (:user_id, :authentication_hash, :authentication_salt, :public_key, :encrypted_private_key, :decryption_key_salt)")
}

Пользователь может войти в систему.

function authenticate_user(user_id, user_password)
    correct_authentication_hash = query("SELECT authentication_hash FROM users WHERE user_id = :user_id")

    authentication_salt = query("SELECT authentication_salt FROM users WHERE user_id = :user_id")
    given_authentication_hash = hash(authentication_salt, user_password)

    return correct_authentication_hash == given_authentication_hash

Секрет может быть предоставлен пользователю-получателю.

function grant_secret(secret_id, secret_data, recipient_id) {
    recipient_public_key = query("SELECT public_key FROM users WHERE user_id = :recipient_id")

    encrypted_secret_data = asymmetric_cipher_encrypt(
        input      => secret_data,
        public_key => recipient_public_key
    )

    execute("INSERT INTO granted_secrets (secret_id, recipient_id, encrypted_data) VALUES (:secret_id, :recipient_id, :encrypted_secret_data)")
}

Наконец, пользователь, которому был предоставлен доступ к секрету (получатель), может получить его.

void retrieve_secret(secret_id, recipient_id, recipient_password)
    encrypted_recipient_private_key = query("SELECT encrypted_private_key FROM users WHERE user_id = :recipient_id")

    recipient_decryption_key_salt = query("SELECT decryption_key_salt FROM users WHERE user_id = :recipient_id")
    recipient_decryption_key = derive_key(recipient_decryption_key_salt, recipient_password)
    recipient_private_key = symmetric_cipher_decrypt(
        input => encrypted_recipient_private_key,
        key   => recipient_decryption_key
    )

    encrypted_secret_data = query("SELECT encrypted_data FROM granted_secrets WHERE secret_id = :secret_id AND recipient_id = :recipient_id")

    secret_data = asymmetric_cipher_decrypt(
        input       => encrypted_secret_data,
        private_key => recipient_private_key
    )

    return secret_data

Надеюсь, это поможет. Это, безусловно, помогло мне реализовать мои идеи.

2 голосов
/ 07 мая 2009

Храните ваши пароли в зашифрованном виде с AES и хорошим надежным ключом. Вместо того, чтобы встраивать ключ дешифрования в приложение, дайте его своим пользователям (консультантам службы поддержки). Затем попросите ваше приложение запросить их, когда им нужно будет найти информацию. Не идеально, потому что все используют один и тот же ключ, но он по крайней мере предлагает некоторую защиту, если ваша база данных когда-либо будет взломана.

1 голос
/ 12 мая 2009

Если вы беспокоитесь о том, чтобы дать консультантам оригинальный пароль пользователя, то это пища для размышлений.

А как насчет генерации временного пароля / токена исключительно для вашего участника поддержки?

Когда клиент звонит, создайте токен и поместите его на карту вместе с идентификатором пользователя. Отправьте этот токен или зашифрованный токен вашему участнику службы поддержки. Затем сотрудник службы поддержки войдет в систему, используя имя пользователя и токен. Система проверит токен на карте validtoken и найдет его действительный токен и предоставит доступ к системе.

Поддержка memeber решает проблему. Затем токен удаляется из карты токенов.

Таким образом, вы никогда не раскрываете оригинальный пароль пользователя консультантам. Таким образом, вы можете хранить пароли пользователей, используя ваши любимые методы безопасности.

Вы можете зашифровать токен с помощью открытого ключа консультанта перед отправкой.

Токенам может быть предоставлено время истечения.

0 голосов
/ 07 мая 2009

Вам не нужно хранить свои пароли в базе данных, просто храните их хэш (например, SHA1). Затем во время входа в систему просто вычислите хеш еще раз и сравните его с отсортированным.

Поверьте, если у вас нет сохраненных паролей, с ваших плеч снимается большой вес.

0 голосов
/ 07 мая 2009

Похоже, сценарий DPAPI был разработан для. Создайте средний уровень, который может проверять подлинность ваших клиентов, а затем использовать DPAPI для шифрования данных перед их сохранением в БД

.
0 голосов
/ 07 мая 2009

Если вам нужно получить пароль в виде открытого текста из базы данных, вам необходимо использовать схему двустороннего шифрования.

Не кладите ключ в ваше клиентское приложение.

Таким образом, вы можете регулярно шифровать данные / менять ключ, если вы беспокоитесь о том, что ключ может быть взломан. Хотя, если ваш ключ достаточно силен и не доступен публично, вы должны быть в безопасности

При отправке паролей через сетевое соединение обязательно используйте SSL для шифрования ссылки.

Установка может выглядеть следующим образом

клиент ---> сервер ---> БД

Сервер расшифровывает пароль и передает его по SSL-ссылке клиенту.

Если у вас нет сервера, и ваши клиенты подключаются напрямую к БД, вы можете попросить клиента вызвать хранимую процедуру для получения пароля в виде простого текста.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...