?

Log in

 
 
27 March 2013 @ 12:03 am
Roots, bloody roots  
Криптографическая атака, описанная здесь, конечно, впечатляет, но я думаю, что ахиллесова пята SSL и других протоколов, основанных на инфраструктуре открытых ключей (PKI), вовсе не в криптографии.

Как браузеры и другие программы, полагающиеся на цифровые подписи, знают, что той или иной подписи можно доверять? Проверок много, но все так или иначе упираются в одно: на компьютере уже имеется некий ключ, который пользуется безоговорочным доверием. Как правило, этот ключ – одно из полей в сертификате какого-то CA, имеющего право выписывать другие сертификаты. Когда браузер проверяет подпись этого CA – будь это подпись на сертификате, на CRL, на ответе OCSP и т.д. – то именно этот заранее установленный ключ и используется для операции “расшифровываем хэш из подписи, вычисляем хэш сами, если совпало – всё ок”.

Такой ключ называется “корнем доверия” (root of trust). Он является отправной точкой для принятия решений о доверии любым другим ключам, сертификатом, документам, но его собственная надёжность сомнению не подвергается.

Операционки (например, Windows) или браузеры (скажем, Firefox) поставляются с целым списком из десятков таких “корневых” сертификатов разных CA. Это коммерческие фирмы, зарабатывающие исключительно на том, что их корневому сертификату доверяют по умолчанию – а значит, они могут делегировать это доверие, выдавая подписанные сертификаты желающим в обмен на мзду. Если на большинстве компьютеров в мире не будет стоять сертификат фирмы VeriSign, значит, выданные ими подписи не могут быть проверены и ничего не стоят – значит, VeriSign вылетит в трубу.

Кроме того, если я админ сети какой-то компании, то я могу завести собственную иерархию доверия, установив на всех компах компании собственный корневой сертификат. И тогда эти компы будут доверять сертификатам, выданным мной внутренним сайтам компании, к примеру – без необходимости заносить денежку VeriSign и её конкурентам.


Так вот, теперь к делу. Читаю я, к примеру, очередную объяснялку про SSL и там говорится что-то вроде: “если на вашем компьютере бегает зловредная малварь, которая заставляет браузер открывать фальшивый сайт банка вместо настоящего (скажем, путём записи в файл hosts), то фальшивый сайт не сможет предъявить сертификат с легитимной подписью и т.д. и т.п.”

Окей. Замечательно. А теперь вопрос: раз уж на моём компьютере бегает малварь, что мешает оной малвари не только в hosts записей понакидать, но и собственный корневой сертификат добавить? И тогда все зубодробительные криптографические проверки благополучно завершатся, и браузер примет фальшивый сайт за милую душу?

Ладно, допустим, против вредоносной малвари у нас антивирус есть. Тогда вопрос похуже: а что мешает вполне легитимной, совершенно не тайной и не вредоносной программе свой сертификат добавить? Причём от юзера даже не скрываясь? А ведь как только это будет сделано, то опаньки: компьютер любой подписи, которую этим сертификатом можно проверить, доверяет автоматически, будь то подпись сертификата сайта, или на исполняемом коде, или на PDF-документе, или на e-mail’е.

То есть вот вам вполне реалистичный вектор атаки: допустим, я пишу пользующуюся популярностью програмку – плагин к браузеру, плеер, игрушку, что угодно – в которой не будет ни одного сомнительного байта, но которая добавит новый сертификат в список корневых. Причём можно даже VeriSign’у денежку уплатить, чтобы их подписью програмку заверить – пускай доверяют. В результате все, запустившие програмку – моя аудитория, доверяющая всему, что я подпишу. Если размер этой аудитории – в сотни тысяч, то у этого появляется вполне конкретный экономический смысл – я могу торговать доверием аудитории, как и сам VeriSign. Могу, скажем, подписать сертификат для каких-нибудь фишеров, заманивающих лохов на фиктивный банковский сайт. Или для ботнетоводов, чтобы впаривали уже вполне троянский софт с заверенной мной подписью.

Никаких технических или легальных ограничений на сей счёт не существует. Есть аппаратные средства, защищающие секретные ключи (смарткарты, TPM) – но они не защищают список корней доверия от записи. Теоретически, можно их приспособить для этого тоже, чтобы без согласия юзера ничего туда попасть не могло – но поможет мало. Потому что люди просто не понимают всех возможных смыслов и следствий этого действия. На тьме сайтов находится совет: если у вас проблемы с сертификатом, просто добавьте его в “Trusted Root Certification Authorities”. Никаких советов, как при этом сузить область его действия, при этом не прилагается – хотя в том же Windows инструменты для этого есть. То есть я мог бы вместо програмки-разносчика просто завести популярный сайт, при заходе на который люди будут получать warning от браузера о недоверяемом сертификате, и написать: “чтобы избавиться от надоедливых предупреждений, просто добавьте наш сертификат в список корневых” – и это будет стопроцентно законно, и никакие аппаратные препоны не помогут.

Если же используется програмка-разносчик, то обнаружить такую схему будет очень непросто – допустим, впарю я вот так корневой сертификат с именем “VeriSign Class 3 Public Primary Certification Authority – G4”. Ну и какой, простите, параноик, обнюхивающий цифровые подписи со всех сторон, запомнит, что он отличается от вполне легального сертификата “VeriSign Class 3 Public Primary Certification Authority – G5”? Не говоря уже о том, что упомнить названия всех легальных CA даже для админа нереально.

Даже если схема обнаружена, побороть её нелегко. Никаких CRL-ей для корневых сертификатов не существует. Надо использовать иные механизмы – те же апдейты к программам, антивирусы, какие-то предупреждения развешивать. Но это опять же штука вероятностная: где-то поможет, где-то нет.


Что же можно поделать? Можно, например, сократить количество доверяемых корней. Тут я опять же возлагаю надежды на схему, интегрирующую сертификаты и DNSSEC – у публичного DNS корень один, так что все цепочки доверия должны приходить в конечном счёте к нему. Проблема в том, что такое положение вещей даёт держателю корня огромную власть: он в состоянии лишить всеобщего доверия кого угодно.

Можно пытаться снижать вероятность подмены сертификатов: допустим, браузер может не только проверять подписи и CRL, но и держать историю, какой сертификат использовался ранее, и выкидывать предупреждение, если он изменился – особенно если вдруг изменился CA, который его подписал. Можно сочетать это с каким-нибудь сетевым сервисом, который будет по требованию проверять сайт – открывать его с адресов в разных сетях по всему миру и убеждаться, что всем клиентам выдан тот же сертификат. Проблема – нарушает принцип KISS, ну и до кучи, возникнет головная боль со всякого рода схемами load balancing.

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

Правильный, на мой взгляд, путь используется в Firefox и Outlook – можно облечь доверием конечный сертификат сайта или автора мэйла, не доверяя подписавшему его корневому. Недостаток: в том, что юзер может привыкнуть жмякать на “make exception” автоматом – что толку тогда во всей схеме?

Ну и самое тяжелое – обучать и объяснять. И муторно в исполнении, и принципу KISS противоречит страшно. :-)


P.S. Ну и напоследок. Пару лет назад была история с иранским хакером, который взломал итальянскую фирму, перепродающую сертификаты Comodo, и сумел подписать ключом Comodo сертификаты для https://mail.google.com, https://login.yahoo.com, https://addons.mozilla.org и ещё к нескольким сайтам. Внимание обсуждающих тогда сосредоточилось, естественно, на подробностях взлома, да на том, вправду ли взломал или блеф (не блеф), да одиночка ли это, или иранское правительство (которому такой взлом мог и вправду быть весьма полезен).

Между тем, наиболее тревожным мне кажется совсем другой аспект: какого чёрта API, предоставляемый Comodo, вообще выдал сертификаты на те же имена, которые уже заверил VeriSign? Между CA, что, никакой координации нету? Чего тогда их надёжность стоит? Если Вася может заказать сертификат на свой сайт https://vasya.com у одного CA, а Петя – на то же имя у другого, и выдать свой сайт за васин, то не значит ли это, что вся безопасность HTTPS – мыльный пузырь?
 
 
Current Music: Sepultura - Roots