Pull to refresh

Comments 56

Лучше бы какой-то другой тэг использовать — Хабр обрезает строки с ssl_ciphers примерно на половине.
UFO landed and left these words here
На самом деле, на нашей статистике IE8 не так много. Куда больше, в разы, Opera 12. И IE8 сам по себе не плох — плох только IE на XP, потому, что шифрование в IE зависит от библиотеки SChannel, а в XP она не умеет ни одного пристойного шифра. IE8 выходил, кажется, вместе с SP3, с которым пришло и обновление SChannel — появилась поддержка 3DES и SNI.

XP уже не поддерживается, а браузеры остались. :(
Если бы мы были в Японии, его бы имело смысл поддержать. А так — сначала нужно понять, какую пользу он приносит, помимо увеличения attack surface.
Использовать шифрсьюты на основе ГОСТов имеет смысл ради экспериментов разве что, или когда сверху сказали (законодательно), что надо. Иные варианты использования даже в голову не приходят. :)
Поправьте, если не прав.
У ГОСТ 28147–89 есть несколько недостатков: во–первых, он медленнее AES даже без учета AES-NI, во–вторых, малый размер блока (64 бита) переносит в область практической достижимости атаки с учетом коллизий CBC, хотя для HTTPS–сессий это менее актуально, чем для VPN–соединений, где объемы трафика куда больше, в–третьих, проблема с тем, что S–боксы не являются частью стандарта (ТК26, наконец, пришел в сознание и опубликовал рекомендацию, но я, честно говоря, не в курсе, насколько она обязательна к исполнению) в–четвертых, если хочется, что бы его считали действительно криптографией, нужно купить сертифицированные криптобиблиотеки

Остановлюсь подробнее на последнем. У нас, как уже писал kyprizel, есть свой HTTP–балансер под названием balancer. Он же терминируетTLS. В качестве библиотек он использует OpenSSL, значит, что не пришлось переписывать, надо бы иметь сертифицированный вариант OpenSSL. Такой, конечно, есть, да и собственно поддержка ГОСТ в ванильном OpenSSL сделана теми же людьми, так что можно было бы использовать, но тут возникает беспокойство о необходимости получения лицензии в ФСБ.

В общем, я про это думал и решил, что с технической стороны алгоритм тридцатилетней давности уже показывает свой возраст и не выглядит достаточно привлекательным на фоне более новых разработок, а со стороны юридической добавляет проблем. И все это ради того, чтобы поддержать 1-2% браузеров с установленным КриптоПРО. Так что, как верно заметил соседний комментатор, пока законодательно не обяжут, связываться не хочется.
1) Это была шутка юмора, относящаяся к «Если бы мы были в Японии».

2) Справедливости ради, ЕМНИП, сертифицированная ФСБ библиотека необходима лишь там, где использование криптографии обязательно согласно законодательству. У вас же нет сертификата NIST на реализацию AES, RSA и SHA, и ни у кого вопроса не возникает. А даже если бы и была, то проверить, что именно эта реализация у вас воткнута в бою ваш клиент никак не может.

3) Проблема не столько в рекоммендации ТК26, а в полном его нежелании взаимодействовать с IANA, IETF и TLS WG.
А в Яндекс.Браузере поддержку ГОСТ не планируете сделать?
Для этого надо добавить поддержку ГОСТ в libnss. Предлагаю вам почитать for fun эту баталию.
Если абстрагироваться от баталии, то проект atoken предлагает работающее решение. Правда для устаревшей версии NSS.
Там про него упомянуто в самом конце. Всё не дойдут руки в нём поковыряться.
А другой путь — в качестве криптоядра chromium использовать openssl вы не рассматривали? В этом случае патч будет существенно меньше.
Возможно, что я создал ложное впечатление, что я принимаю какие-то решения в разработке libnss или chromium, или имею какое-то отношению к Yandex и их браузеру. Это всё не так, поэтому я такие вещи рассматривать могу только в своих фантазиях ) Я был готов помочь с реализацией ГОСТ в libnss, но это как видно, оказалось никому не нужно.

Возвращаясь к вашему вопросу:
1) Как мне кажется, libnss довольно глубоко вшит в хромиум и его отпрысков.
2) Есть некий проект по приведению инициализации криптографии в Linux к одному знаменателю, и там в фаворе systemd NSS.

Касательно использования того или иного криптографического framework'а, могу лишь сказать, что мне они одинаково не нравятся. NSS очень не нравится тем, что у него глобальное состояние. OpenSSL по-мимо своей дурной славы своим неполноценным API. Например, вы не можете с помощью него сделать сертификат на ГОСТовский ключ, который удовлетворяет приказу ФСБ из-за того, что ему нельзя указать тип у полей у тэгов ИНН, СНИЛС и ОГРН.
OpenSSL по-мимо своей дурной славы своим неполноценным API. Например, вы не можете с помощью него сделать сертификат на ГОСТовский ключ, который удовлетворяет приказу ФСБ из-за того, что ему нельзя указать тип у полей у тэгов ИНН, СНИЛС и ОГРН.

Почему же. Можно.
Приведу вам выдержки из кода, использующего API OpenSSL.

1. Собственно таблица «русских» полей:

OpensslObject ruOpensslObjects[] =
{
	{"INN", "INN", "1.2.643.3.131.1.1", V_ASN1_NUMERICSTRING},
	{"OGRN", "OGRN", "1.2.643.100.1", V_ASN1_NUMERICSTRING},
	{"OGRNIP", "OGRNIP", "1.2.643.100.5", V_ASN1_NUMERICSTRING},
	{"SNILS", "SNILS", "1.2.643.100.3", V_ASN1_NUMERICSTRING},
	{"kpFSS", "KP FSS", "1.2.643.3.141.1.2", V_ASN1_UTF8STRING},
	{"rnsFSS", "RNS FSS", "1.2.643.3.141.1.1", V_ASN1_UTF8STRING},
	{"KC1", "KC1", "1.2.643.100.113.1", -1},
	{"KC2", "KC2", "1.2.643.100.113.2", -1}, // TODO: check  sn and ln names for russian policy
	{"KC3", "KC3", "1.2.643.100.113.3", -1},
	{"KB1", "KB1", "1.2.643.100.113.4", -1},
	{"KB2", "KB2", "1.2.643.100.113.5", -1},
	{"KA1", "KA1", "1.2.643.100.113.6", -1},
	{"subjectSignTool", "Subject Sign Tool", "1.2.643.100.111", -1},
}; 


2. Регистрируем «объекты», связанные с «русскими» полями

try {
		for (int i = 0; i != boost::size(ruOpensslObjects); i++)
		{
			int nid = m_openssl->OBJ_create(ruOpensslObjects[i].oid, ruOpensslObjects[i].sn,
			                                ruOpensslObjects[i].ln);
			m_objectsMap[nid] = &(ruOpensslObjects[i]);
		}
	} catch (std::exception& exc) {
		e = exc;
		exceptionThrown = true;
		goto opensslEngineFinish;
	}


3. Собственно функция формирования subject в PKCS#10. «Русские» поля обрабатываются в default.

void Pkcs10Request::addSubjectEntry(const string& name, const string& value)
{
	if (name.empty() || value.empty())
		BOOST_THROW_EXCEPTION(BadParamsException());

	const OpensslWrapper* openssl = m_crypto->openssl();
	int nid = openssl->OBJ_txt2nid(name.c_str());
	int encodingType = 0;
	switch (nid)
	{
		case NID_commonName:
		case NID_organizationName:
		case NID_organizationalUnitName:
		case NID_title:
		case NID_localityName:
		case NID_stateOrProvinceName:
		case NID_surname:
		case NID_givenName:
		case NID_streetAddress:
		case NID_postalAddress:
		case NID_pseudonym:
			encodingType = MBSTRING_UTF8;
			break;
		case NID_pkcs9_emailAddress:
			encodingType = V_ASN1_IA5STRING;
			break;
		case NID_countryName:
			encodingType = V_ASN1_PRINTABLESTRING;
			break;
		default:
			const OpensslObject* obj = m_crypto->object(nid);
			encodingType = obj->asn1enc;
	}

	if (!openssl->X509_NAME_add_entry_by_NID(m_subject, nid, encodingType,
	                                         reinterpret_cast<unsigned char*>(const_cast<char*>(value.c_str())),
	                                         -1, -1, 0))
		BOOST_THROW_EXCEPTION(OpensslException(openssl));
}


Через тулзу openssl сделать то же самое с ходу не удалось, как-то там мутно конфигурируются типы новых OID-ов.
Каюсь, я имел ввиду не API, а тулзу. С тулзой и её конфигом протрахался долго, пока в глубоко в доке не прочитал, что дополнительным полям присвается всегда фиксированный тип, сейчас не вспомню какой: то ли DisplayString, то ли Utf8String.
Может, кому пригодится. С помощью cryptcp (https://www.cryptopro.ru/products/other/cryptcp) можно создать запрос на сертификат с указанием ИНН, ОГРН и т. д. А сам запрос подписать OpenSSL.
Ещё nss смотрит в environment в поисках прекрасной переменной SSLKEYLOGFILE, после чего начинает писать pre-master в указанный файл.

И это поведение не отключается (по крайней мере, недавно это было так и положительных подвижек в эту сторону не было), кроме как патчингом библиотеки (в частности, присутствует в релизных сборках хрома и фф).
Вы шутите? Это же прекрасная мегафича, которая позволяет вам дебажить https соединения с помощью Wireshark.
Эта мегафича крайне удобна для дебага (и я её активно использую, т. к. у меня на серверах предпочтение отдано ECDHE+AESGCM), но очень хочется, чтобы её использование требовало, как минимум, запуска браузера со специальным ключом.
Это, можно сказать, следствие глобальности контекста. В данном случае монопенисуально параметр браузера или переменная среды. Вот openssl позволяет двум независимым сущностям в процессе оперировать либой с совершенно разными наборами настроек. А NSS — нет. Поэтому особой разницы как прокидывать эту настройку в NSS я не вижу. А вы?

SSLKEYLOGFILE=/tmp/my.keylog chrome

или
chrome --ssl-keylog-file=/tmp.keylog


Кроме того, представьте себе ситуацию, когда приложение, использующее nss не умеет такого ключа коммандной строки, а поглядеть shark'ом очень надо…
При использовании env vars есть неявная конфигурация, которая незаметна при запуске chrome/firefox (надо дополнительно проверять наличие установленных env vars). При использовании ключа при запуске конфигурация явная.
Первый пример, как запускать браузер, без установки переменной на весь ваш сеанс шела. Думаю, что это разумный компромис.
Вы при запуске каждого приложения проверяете env? Я — нет. И мне не нравится подход мозилловцев в этом кейсе.

Это похоже на то, если бы mkfs --help выполнял форматирование, если в env проставлено MKFS_TARGET несмотря на то, что у него всего-лишь запросили справку. Даже, если про это знает каждый, это прописано в документации и т. п., но шанс ошибки резко возрастает.
Объясните мне, зачем проверять перед каждым запуском проставленно ли что-либо в env?

Если вы сами имеете свойство проставлять в окружение шелла такие опасные переменные, то это лечится самодисциплиной. Так же как и лечится привычка не сидеть под рутом.

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

А вы, как принято говорить в Яндексе, нерепрезентативны. :)
За что минусанули ivlad не понятно, но ради интереса посмотрел: из популярных браузеров только Firefox поддерживает CAMELLIA, но в силу приоритета предпочтений он никогда не выбирется. Таким образом, вам придется найти/настроить браузер, чтобы CAMELLIA там стояла на первом месте в списке. Эдакий япона-браузер, я бы сказал ) То есть это носит сугубо теоретический характер для Яндекса.

А, например, Гугл выпилил из Chrome все ciphersuite и не протестует против добавления ГОСТового ciphersuite именно по причине, описанной ivlad — увеличение attack surface.
у меня в Fx как раз CAMELLIA и выбирается, если ничего специально не настраивал ни на клиенте, ни на сервере
Значит, либо такие дефолтовые настройки сервера, либо в Fx произошли какие-то изменения в предпочтении ciphersuite'ов. Давайте посмотрим, что скажет тест вашего браузера.
Видимо, это так было раньше. Сейчас первая CAMELLIA встречается на 12-й позиции, что практически нереально.
Если в сервере включена только она, то почему бы и нет )
Firefox поддерживает CAMELLIA, но в силу приоритета предпочтений он никогда не выбирется
Набор шифра всегда выбирает сервер, но он может либо выбрать первый попавшийся среди поддерживаемых браузером, либо выбрать первый попавшийся из своего списка, если настроено серверное предпочтение.

Наивысший приоритет CAMELLIA отдан на контент-серверах Adriver, так что у пользователей Tor Browser и старого Firefox реклама загружается с использованием именно этого шифра.
Чем AES_GCM принципиально лучше AES_CBC?
Не требуется отдельный подсчет MAC? ОК, допустим, выигрыш в производительности.
И там и там с каждым пакетом посылаются и IV и MAC (для GCM аналог — authentication tag). Т.е. на первый взгляд в плане оверхеда тоже примерный паритет.

Было бы интересно, если б кто-нибудь раскрыл этот вопрос подробнее.
Ну, навскидку:
  1. CBC позволяет существовать уязвимостям типа POODLE, более широко — предскаузуемость влияния изменения одного блока на шифрование следующего — плохая идея,
  2. CBC делает уязвимыми коллизии блоков, для AES это не очень применимо, потому что размер блока большой, а для ГОСТ 28147–89 атака представляется практически реализуемой,
  3. GCM можно шифровать параллельно, на нескольких ядрах, в CBC — только последовательно.
Да тот же Beast был реализуем был, за счет последовательного XORа блоков в CBC.
Зачем же его тогда оставили в своих настройках?
Примерно по той же причине, по которой есть 3DES. Мы же в реальном мире живем, где есть браузеры, не поддерживающие TLS1.2 и самые модные–трендовые ciphersuites. Им тоже надо обеспечить поддержку.
Например, все версии Safari на iOS (в том числе 8.3) GCM не поддерживают.
У 3DES кстати абсолютно та же болячка, что и ГОСТа: 64-битный блок.
Начиная с TLS1.1 при использовании шифра в режиме CBC для шифрования каждого блока используется независимый IV, передается явно и лежит в начале зашифрованного блока. Тем самым решая проблемы 1 и 3.
Проблему 3 это не решает, потому, что запрос помещается в один TLS record, и его распаралелить нельзя. А во сколько TLS records поместится ответ — depends. Это неудобно. И все это не отменяет принципиально проблемы CBC.

И не отменяет того, что есть браузеры с максимум TLS1.0 (впрочем, они и режимы GCM не умеют).

Я не говорю, что CBC плох до неприемлемости — если бы мы так считали, не держали бы его у себя. Но у него, как у режима есть недостатки в сравнении с другими режимами. Их можно компенсировать реализацией, но они остаются. Я сам в общем–то долго противился AEAD, дубовая схема с отдельным HMAC выглядит более понятной и потому — более надежной: сначала проверяешь HMAC и только если он сошелся, делаешь что–то еще. Но жизнь внесла свои коррективы и я соглашусь с Адамом Ленгли — «everything less than TLS 1.2 with an AEAD cipher suite is cryptographically broken».
На сколько я понимаю CBC имеет проблемы в плане безопасности именно в контексте реализации в SSL/TLS, а именно потому, что там MAC then CBC.
Реализация AES в режиме CBC then MAC со случайным IV для каждого record, отдельными ключами для шифрования/MAC, и надежной hash-функцией для HMAC выявленных проблем не имеет. Верно?
Возможно я не прав, но мне кажется что параллелизация для AEAD шифров достигается за счет одновременного шифрования соседних блоков на разных процессорах, то есть полностью аналогично CBC. Такие выводы я делаю, исходя из RFC5288 секция 6.2.

В этом разделе говорится про выбор nonce explicit (фактически кусок iv) при использовании нескольких процессоров. Поскольку nonce explicit имеет смысл только на уровне законченного блока, я делаю вывод, что просто независимо шифруются соседние блоки.
CBC вообще не очень надежен в случае атак с выбором шифртекстом.
Ещё неплохие рекомендации у Мозиллы: wiki.mozilla.org/Security/Server_Side_TLS. Правда, они пишут под довольно широкий набор случаев (там, например, есть DSS для аутентификации, который в сертификатах встречается редко)
Кстати, в 2015 году ни Chrome, ни Safari, ни сам Firefox не поддерживают DSS, только Explorer остался.
Затем идет два варианта с шифрованием 3DES: их мы сохраняем в первую очередь для браузеров Internet Explorer на Windows XP с установленным SP3. Internet Explorer использует системную библиотеку Schannel, и в XP с SP3 наконец появилась поддержка 3DES — устаревшего, но все еще устойчивого алгоритма шифрования. Наконец, для несчастных с Internet Explorer 6 на XP мы сохраняем шифры RC4 — других вариантов на этой платформе просто нет. При этом мы осознаем вероятность того, что этот шифр уязвим, поэтому доступен он только в случае хендшейка по протоколу SSLv3. Если клиент подключается с более современным протоколом — TLS 1.0, TLS 1.1 или TLS 1.2 — ciphersuite на основе RC4 не предлагается.
Интересно, как Service Pack 3 добавляет поддержку 3DES, если в это время уже аппаратное ускорение AES в процессорах вводят? Наверно, просто перепутали с хотфиксом, который добавляет поддержку AES в Windows Server 2003, всё это в одно и то же время происходило.

XP даже не первая Windows с поддержкой 3DES из коробки, и у неё поддерживаемые наборы шифров никогда не менялись.

Впрочем, по моей личной оценке, сайтом с самыми плохими ciphersuites в интернете был сайт Госуслуг правительства Москвы login.mos.ru. В свое время он предлагал ciphersuite TLS_NULL_WITH_NULL_NULL — то есть без аутентификации и без шифрования. Впрочем, сейчас приняты меры: задержка на установку TLS соединения с sslabs.com установлен таким образом, что сканер отваливается по таймауту. Но и ciphersuites поправлены, хотя высшим приоритетом стоят RC4-MD5, RC4-SHA и 3DES-SHA, в списке можно найти ECDH — это можно проверить вручную командой openssl s_client с ключом -cipher.
Я с этим сервером уже полтора месяца маюсь. Результаты сканирования доступны здесь: github.com/ssllabs/ssllabs-scan/issues/109
Приоритет совсем наоборот, наивысший 256-битный AES, затем 3DES, затем 128-битный AES, в самом низу RC4.
Если нужна поддержка IE6 на XP, можно включить RC4
Зачем включать RC4, использование которого запрещено, если даже Windows NT 4.0 поддерживает 3DES?
Зачем включать RC4, использование которого запрещено, если даже Windows NT 4.0 поддерживает 3DES?
А, да, это я мутно выразился, извините. Нужно поправить статью в этом месте. Спасибо за внимательность. :)

IE6 умеет по умолчанию только SSLv3 (TLS 1.0 включается где-то в настройках, AFAIR). То есть, у нас две проблемы, на самом деле: ciphesuites и версии SSL/TLS. С SSLv3 и TLSv1 использование блочных шифров открывает уязвимость BEAST. Поэтому если нужно поддерживать IE6, приходится только для SSLv3 делать доступным RC4.

У нас балансер специальным образом запатчен: если подключиться к тему с SSLv3, то RC4 доступен, а если с любым TLS — то нет.

Что касается login.mos.ru, главный анекдот про TLS_NULL_WITH_NULL_NULL все-таки. Возможно, они меняют настройки. Когда я пробовал их вручную проверить, первым выбирался RC4. Но такого хозяйства много, так что это уже не очень занимательно.
У нас балансер специальным образом запатчен: если подключиться к тему с SSLv3, то RC4 доступен, а если с любым TLS — то нет.


Очень интересует этот момент. Каким образом удалось сделать доступность определенных ssl_ciphers только для SSLv3?
Only those users with full accounts are able to leave comments. Log in, please.

Information

Founded
Location
Россия
Website
www.yandex.ru
Employees
over 10,000 employees
Registered

Habr blog