Глава 3. Введение в криптографию
которая бы более эффективно использовала ресурсы сервера. Однако это ни-
кому не нужно. Гораздо дешевле купить несколько аппаратных ускорителей
и работать с существующим протоколом SSL, нежели платить эксперту за
разработку нового протокола. А затем за стандартизацию этого протокола.
А затем за его реализацию в серверах и обозревателях. А затем убеждать
каждого в необходимости перейти на новую версию обозревателя.
Недавно мы придумали хороший аргумент для тех, кто не желает по-
ступаться производительностью в пользу безопасности: “У нас уже есть ку-
ча быстрых и небезопасных систем. Зачем нам еще одна?” Это очень верное
высказывание. Обеспечение безопасности “наполовину” обходится почти в та-
кую же сумму, как и обеспечение безопасности “целиком”, а вот практической
пользы от такой безопасности нет. Мы свято верим, что безопасность нужно
либо обеспечивать хорошо, либо не обеспечивать вообще.
3.9
Сложность
Не существует сложных систем, которые были бы безопасными.
Правило проектирования 1.
Сложность — главный враг безопасности.
Это очень простое правило, тем не менее нам понадобилось немало лет
для его полного осознания. Современные IT-разработчики практически не
справляются с построением сложных систем. Они что-то придумывают, что-
то реализуют и приводят это в рабочее состояние. . . вот, собственно говоря,
и все. Продукты, которые б´ольшую часть времени находятся в работоспособ-
ном состоянии, считаются хорошими, и практически никогда не проводятся
тесты на попытку их преднамеренного разрушения.
Описанная ситуация связана с общепринятым принципом разработки про-
граммного обеспечения: построить систему, протестировать ее на наличие
ошибок, вернуться назад и исправить ошибки, снова протестировать ее на
наличие новых ошибок и т.п. Протестировать, исправить, повторить. Так
продолжается до тех пор, пока руководство компании не прикажет издать
продукт или же пока программистам не надоест с ним возиться. Разумеется,
в результате такого процесса будет получена вполне работоспособная систе-
ма — работоспособная до тех пор, пока будет применяться так, как это было
задумано. Это может быть хорошо с точки зрения функциональности, однако
совершенно не годится для разработки систем безопасности.
Основная проблема данного метода состоит в следующем. Тестирование
обнаруживает только наличие ошибок, притом только таких ошибок, кото-
рые ищут тестировщики. Между тем системы безопасности должны работать
даже под натиском умных и коварных злоумышленников. Систему нельзя
протестировать на все ситуации, в которые ее может поставить нападающий.
3.9. Сложность
59
Поэтому система должна быть безопасной не в результате тестирований и ис-
правлений, а с самого начала разработки.
Представьте себе такую аналогию. Вы пишете довольно большое приложе-
ние на одном из популярных языков программирования. При этом вы стара-
тельно исправляете все синтаксические ошибки до тех пор, пока приложению
не удастся пройти первую компиляцию. Как только это происходит, вы без
какого-либо дальнейшего тестирования упаковываете диск с приложением
в красивую коробку и продаете покупателю. Разумеется, никто не ожидает
получить действительно функциональный продукт подобным образом.
Между тем именно это и происходит в наши дни с системами безопасно-
сти. Их невозможно протестировать, так как никто не знает, на что их нужно
тестировать. При этом, если в системе безопасности обнаружится хотя бы од-
на ошибка, она сведет на нет назначение всей системы. Таким образом, един-
ственный способ получить безопасную систему — это с самого начала делать
ее надежной и безопасной. Это, в свою очередь, требует, чтобы система была
простой.
Единственный известный нам способ построить простую систему — раз-
бить ее на модули. Это прописная истина программной инженерии. В на-
шем случае, однако, нельзя позволить себе вообще ни одной ошибки, поэто-
му к разбивке на модули необходимо подойти со всей возможной строгостью.
Вот наше основное правило.
Правило проектирования 2.
Корректность работы должна быть локаль-
ным свойством.
Другими словами, одна часть системы должна функционировать коррект-
но, независимо от того, как функционирует вся остальная система. Только не
пытайтесь сказать нам что-нибудь наподобие: “Это не проблема, потому что
оставшаяся часть системы просто не может дать сбой”. Оставшаяся часть
системы может иметь ошибку или же измениться в какой-нибудь будущей
версии. Каждая часть системы должна отвечать за свою собственную функ-
циональность.
Как вы вскоре убедитесь, мы еще не раз будем применять это правило
на протяжении последующих глав книги. Именно оно стало причиной того,
что большинство наших решений оказались более консервативными, чем те,
которые принято применять в разработке современных систем.
|