Bitmask
Зашифрованная коммуникация для простых смертных 
 (супергероям тоже добро пожаловать)

Подробности криптографии Bitmask

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

Аутентификация – парольная аутентификация (SRP)

Bitmask использует парольную аутентификацию (Secure Remote Password, SRP) для проверки подлинности сервис-провайдера. SRP – это вид доказательства с нулевым разглашением для аутентификации посредством имени пользователя и пароля, которая не дает серверу копию действительного пароля. Как правило, системы паролей работают путем отправки копии пароля в незашифрованном виде серверу, который затем хеширует этот пароль и сохраняет хеш. Благодаря SRP, клиент и сервер договариваются о “верификаторе пароля” после нескольких проходов “туда-обратно”. У сервера никогда нет доступа к незашифрованному паролю.

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

В настоящее время мы используем 1024-битные параметры дискретного логарифма. Мы изучаем их увеличение до 2048-битных.

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

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

У нас есть три плана на будущее, чтобы преодолеть эти потенциальные проблемы:

  1. Разрешить использование дополнительного длительного случайного ключа, который используется как часть процесса аутентификации (необязательно). Например, каждое устройство, на котором установлен Bitmask, могло бы иметь “ключ устройства”, и пользователь должен был бы авторизовать эти ключи устройства, прежде чем они могли бы запускать Bitmask на этом новом устройстве.
  2. Мы также планируем включить в Bitmask фильтр Блума 10,000 наиболее часто используемых паролей. По некоторым данным, 98,8% всех пользователей выбирают пароль из этих 10,000. Фильтр Блума этих паролей является относительно небольшим, и мы можем просто запретить пользователю выбирать любой из них (хотя и с некоторыми ложными срабатываниями).
  3. Разрешить провайдерам запрещать аутентификацию через веб-приложения. Аутентификация будет происходить посредством приложения Bitmask, которое затем загрузило бы на веб-сайт с помощью сеансового токена, который оно получило. Таким образом, критический код аутентификации SRP никогда не будет загружаться от провайдера.

Для получения дополнительной информации смотрите:

Транспорт – TLS

Клиент Bitmask часто делает различные соединения с провайдером, используя TLS. Например, чтобы проверить есть ли обновление списка VPN-шлюзов.

Когда сервис-провайдер впервые добавляется Bitmask, сертификат центра сертификации от провайдера загружается с помощью обычного TLS-соединения, аутентифицированного с помощью существующей системы сертификации X.509. Это единственный момент, когда Bitmask полагается на систему сертификации.

Все последующие соединения с тем провайдером используют центр сертификации конкретно для этого провайдера для проверки подлинности TLS-соединения. По сути, это форма пиннинга сертификатов и TOFU. Для того, чтобы внешнему злоумышленнику выдать себя за провайдера, он должен предоставить ложный сертификата сервера X.509, аутентифицированный центром сертификации, а затем перехватить и переписать весь последующий трафик между клиентом Bitmask и провайдером.

Если провайдер был предварительно установлен приложением Bitmask, то отпечаток сертификата центра сертификации для этого провайдера известен заранее. В подобных случаях нет нужды когда-либо полагаться на систему сертификации X.509.

По умолчанию сертификат центра сертификации для конкретного провайдера использует 4096-битный RSA и SHA256, сертификаты сервера используют 4096-битный RSA и SHA256. Эти значения по умолчанию можно легко изменить.

Все TLS-соединения используют шифры PFS.

Хранение – Soledad

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

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

На данный момент параметры scrypt такие:

N (параметр стоимости соотношения время/память) = 2^14 = 16384
p (степень параллельности) = 1
r (длина блока, перемешиваемого SMix()) = 8
dkLen (длина выходного ключа) = 32 байта = 256 бит

Мы рассматриваем использование большего значения для N.

Локальное хранение

Локальная база данных SQLite с блочным шифрованием использует AES-256-CBC, используя первые 256 бит storage_secret. Смотрите github.com/kalikaneko/python-u1dbcipher и sqlcipher.net.

Удаленное хранение

Подокументное шифрование документов, хранящихся удаленно, использует симметричное шифрование с AES-256-CTR или шифр XSalsa20, использующий 256-битные ключи. Для этого используется библиотека pycryptopp. Ключ и MAC, используемые для шифрования каждого отдельного документа, получаются следующим образом:

storage_secret_a = первые 256 бит секретного значения хранилища
storage_secret_b = все после первых 256 битов секретного значения хранилища
document_key = hmac(document_id, storage_secret_b)
document_mac = hmac(document_id | document_revision | iv | ciphertext, hmac(document_id, storage_secret_a)

Каждый документ имеет свой собственный ключ. document_revision в MAC документа предотвращает откат к старой версии документа. HMAC использует SHA256.

Некоторые документы в удаленном хранилище данных пользователя добавляются провайдером, например, в случае нового входящего сообщения электронной почты. Эти документы используют асимметричное шифрование, с каждым документом, зашифрованным с использованием пользовательского открытого OpenPGP-ключа. Библиотекой, которую мы используем для этого, является форк Айсис python-gnupg. Эти документы лишь временно хранятся пободным образом: как только клиент увидит их, они остаются в незашифрованном виде и повторно шифруются с использованием других методов.

Транспорт

TLS, как описано выше. Скоро будет CurveZMQ.

Зашифрованный туннель – OpenVPN

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

tls-cipher

Параметр --tls-cipher определяет процесс аутентификации сеанса OpenVPN. Если он будет скомпрометирован, то вашу коммуникацию сможет прослушивать злоумышленник с помощью атаки посредника. TLS часть OpenVPN аутентифицирует сервер и клиент друг с другом, и согласовывает случайное значение, используемое в значении пакетной аутентификации и пакетном шифровании.

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

На данный момент, мы выбрали DHE-RSA-AES128-SHA. Самое главное заключается в выборе шифра, который поддерживает PFS, как это делают все шифры DHE.

Мы выбрали AES-128 потому что известны слабости алгоритмов смены ключей AES-192 и AES-256. Неизвестны слабости к атакам прямого перебора на полный 14-раундный AES-256, однако слабости AES-256, использующего другие числа раундов, достаточно, чтобы рекомендовать AES-128 вместо AES-256 в целом. Для получения более подробной информации смотрите статью Брюса Шнайера Еще одна новая атака на AES.

Мы бы предпочли использовать ECC вместо RSA, и в конце концов планируем это сделать. Это немного сложнее и включает в себя изменения в нашем коде TLS во многих местах (перекомпиляции OpenVPN и изменение библиотек генерации сертификатов, используемых системными администраторами и API провайдеров).

Текущий стандарт для клиентских и серверных сертификатов x.509, используемых OpenVPN, является 2048-битный RSA и 4096-битный RSA (соответственно) с SHA256. Они также легко настраиваются провайдером (чтобы увидеть все варианты, запустите leap inspect provider.json).

auth

Параметр --auth определяет какое хеш-значение используется для аутентификации каждого пакета трафика с помощью HMAC.

Мы решили оставить по умолчанию SHA1 вместо SHA256. Если злоумышленник может нарушать SHA1 HMAC на каждом пакете в режиме реального времени, у вас проблемы больше, нежели только с VPN.

cipher

Параметр --cipher определяет как шифруются действительные пакеты трафика. Мы выбрали AES-128-CBC.

Значение этого параметра OpenVPN по умолчанию, вероятно, на самом деле лучше, чем AES-128, так как это Blowfish. Мы выбрали AES-128, потому что шифр TLS уже полагается на AES-128. Мы, как правило, предпочитаем режим шифра OFB вместо CBC, однако в руководстве по OpenVPN говорится, что “рекомендуется CBC, а CFB и OFB следует рассматривать как расширенные режимы”.

obfsproxy

Obfsproxy опционально использоется так, чтобы VPN-трафик не распознавался как VPN-трафик для кого-либо, кто осуществляет мониторинг сети. Obfsproxy использует модули, называемые встраиваемыми транспортами, чтобы скрыть основной трафик. Различные транспорты могут использовать или не использовать шифрование и иметь различные реализации и выбор схем шифрования.

Мы выбрали подключаемый транспорт Scramblesuit, который использует унифицированный Диффи-Хеллмана для начального рукопожатия и AES-CTR 256 для данных приложения.

Зашифрованная электронная почта – OpenPGP

Автоматически генерируемая пара ключей пользователя использует 4096-битный RSA для главного подписывающего ключа.

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

Все ключи хранятся в Soledad.

Bitmask пока не поддерживает ECC ключи.

Bitmask использует GnuPG. Библиотекой python, которую мы используем, является форк Айсис python-gnupg.

Безопасные обновления – TUF

Безопасные обновления осуществляется с помощью TUF, они используют 4096-битные RSA-ключи OpenSSL с pyCrypto. Существует три ключа, участвующие в процессе обновления (корневой, целевой и временной метки).

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

Разное

OpenSSH

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

DNSSec

Будет написано.

StartTLS + DANE

Будет написано.