Глава 9. Проблемы реализации. Часть I
операций, и лишь небольшая его часть непосредственно касалась вывода сим-
вола на экран. Если бы интерфейс процедуры позволял указывать в качестве
аргумента не символ, а строку символов, тогда печать целой строки выпол-
нялась бы лишь немного медленнее, чем печать одного символа. Результатом
такого неудачного проектирования стала ужасающе медленная скорость вы-
вода на экран всех компьютеров, работающих под управлением DOS. Этот же
принцип касается и проектирования криптографических систем. Убедитесь,
что работа может выполняться сразу большими порциями. Затем оптими-
зируйте только те части программы, влияние скорости работы которых на
общую производительность системы может быть
измерено
и является суще-
ственным.
9.4.3
Утверждения
Утверждения (assertions)
— это хорошее средство, с помощью которого
можно повысить качество кода
5
.
Реализуя криптографический код, необходимо подходить к нему с точки
зрения “профессиональной паранойи”. Каждый модуль не доверяет другим
модулям и всегда проверяет достоверность параметров, накладывает ограни-
чения на вызывающую последовательность и отказывается выполнять небез-
опасные операции. В большинстве случаев это описывается явными утвер-
ждениями. Если спецификации модуля утверждают, что перед использовани-
ем объекта его необходимо инициализировать, тогда попытка использования
объекта до его инициализации приведет к возникновению ошибки утвержде-
ния. Ошибки утверждения всегда должны приводить к аварийному заверше-
нию программы с выдачей подробного сообщения о том, какое из утвержде-
ний было нарушено и почему.
Общее правило выглядит следующим образом: каждый раз, когда вы вы-
полняете какую-либо значимую проверку внутренней согласованности систе-
мы, добавьте к ней утверждение. Постарайтесь перехватить как можно боль-
ше ошибок (и собственных, и допущенных другими программистами). Ошиб-
ка, перехваченная с помощью утверждения, не приведет к появлению “бреши”
в системе безопасности.
Некоторые программисты реализуют проверку утверждений в процессе
разработки программного обеспечения, однако отключают ее в готовом про-
дукте. Хотелось бы знать, кто это выдумал. Что бы вы сказали об атомной
электростанции, операторы которой тренируются работать с реакторами при
включенных системах безопасности, а затем отключают их на настоящем
5
Мы знаем, что наша книга потихоньку превращается в урок программирования, но
что поделать? Мы постоянно вынуждены повторять эти, казалось бы, очевидные вещи
программистам, с которыми работаем.
9.4. Качество кода
171
реакторе? Или о парашютисте, который одевает запасной парашют на тре-
нировках, но снимает его, когда выпрыгивает из самолета? Зачем кому-то
вообще понадобилось отключать проверку утверждений в готовом продук-
те — ведь это, по сути, единственное место, где она нужна? Если в процессе
функционирования реальной системы произойдет нарушение утверждения,
мы всего-навсего получим ошибку программирования. Игнорирование ошиб-
ки, в свою очередь, может привести (и, скорее всего, приведет) к выдаче
неверного ответа, потому что по крайней мере одно предположение, сделан-
ное кодом, будет неправильным. Выдача неверных ответов — это, пожалуй,
худшее, что может сделать программа. Гораздо лучше проинформировать
пользователя о возникновении ошибки программирования, чтобы он не дове-
рял ошибочным результатам, выданным программой. Никогда не отключайте
проверку ошибок!
9.4.4
Переполнение буфера
Современной IT-индустрии должно быть стыдно за появление в нашей
книге раздела с таким заголовком. Проблемы переполнения буферов пресле-
дуют нас на протяжении уже 40 лет. Все это время в мире существовали
и решения для борьбы с ними. Некоторые из ранних языков программиро-
вания высокого уровня, например Algol 60, полностью решали эту проблему
путем введения обязательной проверки границ массива. К сожалению, даже
несмотря на наличие массы поистине замечательных решений, переполнение
буферов до сих пор является причиной более половины всех проблем безопас-
ности, возникающих в Internet. Устранять же эти проблемы никто не собира-
ется. Мы считаем это преступной халатностью. Что бы мы подумали, если бы
производитель автомобилей сделал бензобак из оберточной бумаги? Конечно
же, при определенной доле везения машина могла бы прекрасно ездить и с та-
ким бензобаком, но руководство компании-производителя все равно угодило
бы за решетку. Между тем целые отрасли IT-индустрии ведут себя так, буд-
то не являются ответственными за последствия своих действий. (Возможно,
наши юристы разрешают им свободно отказываться от своих обязательств,
что было бы неприемлемо в любой другой области.) Наблюдая подобное от-
ношение к программному обеспечению, мы часто задумываемся: а стоит ли
вообще пытаться внедрять что-нибудь такое сложное, как криптография?
К сожалению, мы не в состоянии изменить текущее положение дел. Мы
можем лишь посоветовать вам, как написать хороший криптографический
код. Откажитесь от языков программирования, которые допускают перепол-
нение буфера. В частности, не используйте C или C++. И никогда не от-
ключайте проверку границ массива, какой бы язык вы не использовали. Это,
172
Достарыңызбен бөлісу: |