6

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

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

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

Моим подходом было бы создание асимметричной пары ключей на клиенте, публикация открытого ключа на сервере вместе с зашифрованной копией секретного ключа (зашифрованного с помощью пароля пользователя). Пользователи могут затем отправлять зашифрованные сообщения другим пользователям, используя опубликованный публичный ключ получателя; когда пользователю необходимо расшифровать сообщение, его (зашифрованный) закрытый ключ извлекается на клиенте с сервера, расшифровывается с помощью пароля, предоставленного пользователем, а затем используется для дешифрования сообщений.

Имеет ли это смысл? Есть ли недостаток в этом дизайне системы? (кроме слабости от пользователей, выбирающих короткие или плохие пароли) Этот подход уже используется в подобных сценариях?

Спасибо :)

+0

Как описано, это похоже на то, что делает hushmail.com. У них есть сводки на их сайте, описывающие безопасность. –

+0

Спасибо, я посмотрю на них. – Patonza

ответ

2

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

Это не сработает.

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

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

Пользователи должны доверять CA, что может быть более приемлемым, чем доверять администраторам сервера. Но также должен быть защищенный от несанкционированного доступа способ хранения сертификата ЦС. На практике это часто делается с использованием MAC-кода на основе пароля (код аутентификации сообщения). Или CA может быть подписана цифровой подписью с закрытым ключом пользователя (никогда не видел этого, но это сработало). Но сложной частью будет получение сертификата ЦС из надежного источника, минуя ненадежный сервер.

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

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

+0

Да, похоже, это не сработает. Думаю, мне нужно будет найти способ использования доверенного ЦС :) Спасибо за совет. В любом случае, просто чтобы знать, что сервер не был взломан, злоумышленник, который может получить доступ только к * read *, не сможет ничего перехватить, не так ли? Кроме того, если доверие назначается единовременно с другой системой (например, с использованием клиента, который может проверять доверенный ЦС), а затем зашифрован на сервере, то он должен работать, не так ли? – Patonza

+0

@Patonza - Да, если доверие было установлено первоначально с доверенным ЦС, клиент мог бы хранить открытый ключ партнера на сервере * аутентифицировать * его (не * шифрование *) своим собственным паролем. Поскольку сохраненные данные защищены MAC, сервер не может вмешиваться в него. – erickson

+0

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

1

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

  • При шифровании закрытого ключа, использовать что-то вроде PBKDF2 с солью и некоторые довольно большое количество его итераций.
  • Возможно, это подразумевается, но вместо шифрования открытым ключом, вероятно, имеет смысл генерировать случайный ключ (например, 32 байта случайных данных при использовании, например, AES-256). Шифруйте сообщение с помощью этого ключа, зашифруйте ключ открытым ключом и отправьте обе части.
  • Как описано, идентификатор отправителя отсутствует. Это позволяет отправлять чисто анонимные сообщения. Это может быть предназначено, но если нет, то потребуется некоторая идентификация/аутентификация.
  • В некотором роде, аналогичном предыдущей записи, аутентификация сообщения не описана. Злоумышленник может изменить зашифрованное сообщение, и получатель не сможет сказать, что он был изменен. Хотя, если это текстовое сообщение, было бы довольно ясно, что оно было изменено, потому что это был бы просто искаженный текст. Однако есть некоторые типы данных, которые, возможно, не так просто определить, были ли они изменены.
+0

Благодарим вас, что ваша точка зрения на идентификацию отправителя/аутентификацию сообщения, хотя и не мой приоритет в этом конкретном проекте, интересна: возможно, сообщения могут быть подписаны с другой ключевой парой, и клиенты могут хранить зашифрованный каталог ключей известных/доверенных отправителей на сервере - Я займусь этим. И я буду следовать вашим советам относительно PBKDF2, который, кажется, является отраслевым стандартом для укрепления ключа. :) – Patonza

+0

@Patonza - Без аутентификации вы не можете иметь конфиденциальность. Конфиденциальность означает хранить секрет от «кого-то». Если вы не знаете, с кем разговариваете, откуда вы знаете, что это не «кто-то»? – erickson

+1

P.S. Хотя я считаю, что этот ответ неверен (это подразумевает, что предлагаемая система позволит только предполагаемому получателю расшифровать сообщение), совет в каждом марке очень полезен и должен быть тщательно рассмотрен при внедрении реальной системы. – erickson

1

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

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

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

+0

Я не предполагаю, что код клиента должен быть загружен с сервера. Он может быть сохранен только для чтения на клиенте. Симметричное шифрование здесь не является выбором, потому что пользователям придется «встречаться», прежде чем они смогут обмениваться данными. Спасибо за совет в любом случае :) – Patonza

1

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

Смежные вопросы