Безопасность (шифрование) дилемма

Для приколов. Если вам нужно часто делать подобные вещи, можно заключить их в мета-функцию. Вот возможная реализация в :

#include 

template
struct propogate_cv_to_type{};

template
struct propogate_cv_to_type>
{ using type = typename Trait::type; }; 

template
struct propogate_cv_to_type>
{ using type = typename Trait::type const; }; 

template
struct propogate_cv_to_type>
{ using type = typename Trait::type volatile; }; 

template
struct propogate_cv_to_type>
{ using type = typename Trait::type const volatile; }; 

Это дружественно к SFINAE, поэтому, если передаваемый тип не имеет члена ::type, он тоже не будет. В противном случае он выставляет тот же тип, перенаправляя на него квалификаторы.

Вот это , когда применяется к вашему примеру.

7
задан TravisPUK 9 May 2009 в 22:56
поделиться

7 ответов

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

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

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

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

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

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

4
ответ дан 7 December 2019 в 01:25
поделиться

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

0
ответ дан 7 December 2019 в 01:25
поделиться

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

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

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

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

Настройка может выглядеть так

client ---> server ---> DB

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

Если вы этого не сделаете.

0
ответ дан 7 December 2019 в 01:25
поделиться

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

2
ответ дан 7 December 2019 в 01:25
поделиться

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

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

-3
ответ дан 7 December 2019 в 01:25
поделиться

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

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

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

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

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

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

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

6
ответ дан 7 December 2019 в 01:25
поделиться

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

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

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

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

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

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

У токенов может быть установлен срок действия.

1
ответ дан 7 December 2019 в 01:25
поделиться
Другие вопросы по тегам:

Похожие вопросы: