(Возврат на основную страницу)
Криптография в SQL Server 2005. Кому это нужно?
Эта статья не про то, что криптография — бесполезная технология. Эта статья про то, что криптография не является универсальным решением любых проблем. Информация, которая содержится в статье, не привязана к какому-то конкретному продукту; статья не о том, как криптография реализована, например, в SQL сервере, а о вопросах применения криптографии в целом. Ограничения, о которых рассказано в статье, — это ограничения стандартных криптографических методов, а не ограничения их реализации в каком-то конкретном продукте.
В последнее время я видел много попыток применения криптографии для решения проблем, где реально криптография не решает ничего. Поэтому в этой статье я решил рассказать, почему криптографию не надо считать какимто волшебным средством, которое достаточно применить к данным, чтобы сделать их защищенными. Для того чтобы понять, почему это так, мы должны знать несколько базовых фактов, касающихся криптографии. Таких фактов не так много, но они действительно важные.
Для понимания статьи не требуется глубоких знаний в области криптографии. Единственное, что вы должны знать о шифровании, — это то, что оно преобразует данные в форму, в которой они теряют всю свою ценность, если не известен соответствующий дешифрующий ключ (decryption key). Алгоритмы шифрования, где ключ шифрования (encryption key) совпадает с дешифрующим ключом, — называют симметричными алгоритмами шифрования. Если для шифрования и дешифрования используются разные ключи, то такие алгоритмы называют асимметричными алгоритмами шифрования.
Факт 1: шифрование не избавляет от необходимости защищать данные
Маленькая деталь, но очень важная. Если мы хотим защитить какието данные, шифрование не может полностью решить эту задачу, оно просто уменьшает объем информации, которую мы должны защищать. Вместо того чтобы защищать большой объем информации, мы должны защищать маленький — дешифрующий ключ (decryption key).
Это позволяет уменьшить сложность задачи. Например, если вы хотите сохранить в секрете 100 страниц информации, то один из способов сделать это — запомнить все, а затем сжечь. Но очень немногие люди способны на это. Поэтому более практичным решением будет зашифровать весь объем информации, используя некоторый пароль (ключ), и запомнить только его. Принципиально то, что вы все равно должны защищать некоторую информацию, так как если она будет скомпрометирована (раскрыта), то и все ваши данные будут скомпрометированы.
Так что зашифрованные данные защищены лишь настолько, насколько вы можете защитить ключ, который расшифровывает их.
Но как защитить ключ? Шифрование его другим ключом ничего не решает, так как надо будет защищать новый ключ. Поэтому мы вынуждены использовать для защиты ключа один из следующих методов контроля доступа к данным:
(1) — нечто, что вы знаете (например, пароль или PIN);
(2) — нечто, что у вас есть (например, магнитная карта);
(3) — нечто, что только вы можете предъявить (например, отпечаток пальца, рисунок сетчатки глаза, голос).
Например, для защиты дебетовых карт используется комбинация (1) и (2). (3) сложнее, потому что, например, методы идентификации голоса должны быть способны отличить «живой» голос от записи. Кредитные карты, в случае, если реализована проверка подписи или фотографии, реализуют комбинацию (2) и (3).
Факт 2: зашифрованные данные бесполезны до тех пор, пока они не будут расшифрованы
Это очевидно, не правда ли? Но этот факт часто игнорируется. Целью шифрования является сокрытие значения данных, что означает, что мы не получим много толку от этих данных, пока они зашифрованы. Если бы это было не так, то тогда было бы мало толку от шифрования.
Факт 3: дешифрование невозможно без соответствующего ключа (decryption key)
Тоже очевидный факт. Когда мы применяем шифрование, мы как раз и хотим быть уверены, что расшифровать информацию, не имея ключа, невозможно.
Факт 4: создание криптографических алгоритмов совсем непростое дело
Если вы возьмете любую приличную книгу по криптографии, то сразу поймете, что создать хороший алгоритм шифрования, — это совсем не то, что может сделать кто угодно. Если вы не посвятили годы жизни науке криптографии, вы должны использовать стандартные алгоритмы, утвержденные научным сообществом, вместо того чтобы придумывать собственные.
Факт 5: нет ничего волшебного в криптографии
Если вы можете прочитать эту статью до конца и то, что здесь написано, не будет выглядеть для вас чемто бессмысленным, то, вероятно, вы согласитесь с этим фактом.
Какие ключевые следствия из этих фактов?
Следствие 1: защита дешифрующего ключа (decryption key) — обязательное условие для защиты зашифрованных данных
Это следует из факта 1. Если мы не можем защитить дешифрующий ключ, то применять шифрование нет никакого смысла. Так как если кто угодно может получить ключ, то значит, кто угодно может и расшифровать данные.
Следствие 2: система,
которая делает «осмысленные» запросы к зашифрованным данным, нуждается в доступе
к дешифрующему ключу
Чтобы использовать зашифрованные данные, система должна предварительно расшифровать их (факт 2), а сделать это без дешифрующего ключа невозможно (факт 3).
Шифрование может помочь защититься от злоумышленника, который может получить доступ только к зашифрованным данным, но не к ключу. Это правильный сценарий использования шифрования. Например, шифрование поможет, если злоумышленник похитил зашифрованную базу данных, при условии, что ключ украден не был.
Давайте рассмотрим несколько связанных с базами данных сценариев, достаточно часто встречающихся, но для которых применение шифрования не приносит значимой пользы.
Сценарий 1: DRM (система защиты авторских прав)
DRM обычно используется для защиты медийных данных, таких как музыка и фильмы, но в данном случае я использовал эту аббревиатуру для следующих, относящихся к базам данных, сценариев:
«Я хотел бы сделать так, чтобы заказчик мог использовать мое приложение и базу данных, но при этом, чтобы он не мог получить доступ к реальным данным, которые хранятся в базе данных. Я думаю, что шифрование базы данных мне поможет».
К сожалению, шифрование не поможет. Причина заключается в том, что заказчику нужно обеспечить возможность работы с базой данных, а согласно факту 2 и следствию 2 расшифровывающий ключ должен присутствовать гдето на машине заказчика. Это сразу ломает всю защиту. Так как нет на машине такого места, куда можно было бы спрятать какуюто информацию, так чтобы хозяин (администратор) машины не мог ее получить. Так как ключ может быть получен то, следовательно, база данных может быть расшифрована и защита будет снята.
Шифрование в данном случае будет работать как запутывание (obfuscation). Это та же ситуация, что и со старой функцией CREATE PROCEDURE ... WITH ENCRYPTION в SQL Server. Эта функция не способна на практике защитить чтолибо, потому что в данном случае это просто невозможно сделать. Поступали предложения усилить алгоритм шифрования, используемый этой функцией. Но это не проблема (для шифрования здесь используется алгоритм RC4). Никто никогда не взламывал сам алгоритм, гораздо проще выяснить, откуда система берет ключ. Можно изменить алгоритм, но все те же проблемы останутся.
Разница между запутыванием и шифрованием заключается в следующем: запутывание полагается главным образом на алгоритм, раскрытие которого ведет к возможности взлома. Шифрование полагается на ключ, а не на алгоритм — даже зная алгоритм, злоумышленник ничего не сможет сделать без ключа. Применение шифрования и запутывания для ключа в целом дает тот же эффект, что и запутывание.
Нельзя сказать, что запутывание абсолютно бесполезная вещь. Запутывание имеет смысл, когда затраты, которые потребуются на взлом, больше, чем возможная польза (прибыль) от этого. Чем коммерчески успешнее продукт или метод запутывания (obfuscation method), тем выше вероятность, что он будет взломан. Так происходит, потому что больше данных защищено с его помощью, и, соответственно, больше выгоды можно получить от взлома. Это в большей степени вопрос экономики, нежели безопасности.
Сценарий 2: защита от администратора
«Я хочу зашифровать данные в базе данных, для того чтобы у администратора не было возможности видеть их».
К сожалению, в этом сценарии шифрование также помочь не может. Причина та же: для того чтобы приложение могло обрабатывать данные, расшифровывающий ключ должен присутствовать в системе. Это делает его доступным для администратора, так как он имеет в системе неограниченные права.
Персональные компьютеры, как следует из названия, изначально создавались как персональные устройства. Только благодаря гигантскому прорыву в области аппаратных средств за прошедшие два десятилетия эта изначально скромная по своим возможностям машина стала способна решать все более и более сложные задачи, которые требуют различного уровня безопасности. Поэтому сделать так, чтобы какаято информация присутствовала в системе, а администратор не мог ее увидеть, невозможно. Попытка защищать информацию от администратора машины подобна попытке защитить ценности от владельца гостиницы — вы можете предъявить ему иск после того, как он украл их, но вы не можете помешать ему сделать это.
Это чрезвычайно дорого — сделать машину и программное обеспечение для нее так, чтобы можно было гарантировать полное разделение обязанностей. А использование такой системы, вероятно, было бы довольно неудобным. Поэтому, неудивительно, что персональные компьютеры таких гарантий дать не могут.
Сценарий 3: защита от хакерских атак действующей базы данных
«Если злоумышленник взломает мою базу данных, он сможет получить доступ к важной информации, но если я зашифрую ее, то она будет бесполезной для него».
Это может быть так, а может быть и не так. Все зависит от того, как хакер проник в систему и как используются зашифрованные данные. На практике, к несчастью, я думаю, что в большинстве случаев это будет не так.
Рассмотрим как пример недавно имевший место случай похищения данных. Злоумышленник смог воспользоваться уязвимостью типа «внедрение SQL» (SQL injection) для того, чтобы получить из базы данных номера социальных страховок. Расследование инцидента показало, что данные не были зашифрованы. Но если бы они всетаки были зашифрованы, помогло бы это?
Приложение, вероятно, использует эту информацию, делая ее доступной в незашифрованном виде для авторизованных пользователей. Если вторжение было совершено под учетной записью авторизованного пользователя, то злоумышленник, безусловно, смог бы получить эту информацию так же, как если бы она не была зашифрована.
Слишком много «если»? Может быть, но в любом случае нельзя гарантировать, что шифрование защитит данные от похищения в результате атаки хакера на действующую систему. Особенно если шифрование было сделано «прозрачно», в целях удобства и простоты использования. В этом случае нет никаких барьеров против злоумышленника, кроме системы авторизации. Такое шифрование абсолютно не защищает от атак типа «внедрение SQL».
Заключение
Шифрование не является «серебряной пулей» безопасности. Шифрование данных не обязательно означает, что данные автоматически становятся защищенными. К сожалению, зашифрованные данные должны быть расшифрованы, прежде чем они могут быть использованы, и в этот момент они становятся уязвимыми. Мы можем гарантировать безопасность, основываясь на шифровании в ряде сценариев. Но использование шифрования во всех сценариях подряд абсолютно не позволяет говорить о какомто повышении уровня безопасности.
Если вы хотите узнать о шифровании больше, чем я смог рассказать в этой статье, то рекомендую книги, которые написал Брюс Шнайер (Bruce Schneier, http://www.schneier.com/). Он в течение многих лет пишет об опасностях использования криптографии без должного уровня понимания предмета. Пока я писал эту статью, я не мог избавиться от чувства, что я много раз повторяю некоторые из идей, которые Брюс тоже часто повторяет в своих книгах. Возможно, он делает это по той же самой причине, что и я — потому что некоторые ошибки в области безопасности постоянно повторяются.
Параллельное обновление статистики
Недавно мне пришлось столкнуться с напоминанием о значении обновления статистики SQL Server с полным сканом: у нас была система, получавшая плохой план запроса, который последовательно затыкал один из процессоров на несколько часов за раз. Если приходили множественные запросы к одним и тем же данным, то отнималось еще больше процессоров, что доходило временами до 100% использования всех процессоров. Запрос был простым, и мы в течение некоторого времени оказались выбиты из колеи этой проблемой. Выяснилось, что в поддержке затрагиваемой базы данных просто была слишком низкая частота обновления статистики, что и приводило к тому, что оптимизатор выбирал плохой план. Изменение на обновление статистики с полным сканом решило проблему.
Тем не менее обновление статистики с полным сканом может быть медленным и дорогостоящим в большой системе, а одно задание по обновлению статистики на целую базу может легко превысить ночное время обслуживания. Это подало мне идею создать задания, которые могли бы обновлять статистику в системе параллельно, как описано далее.
Примечание Эта методика специально разработана для обновления статистики вручную и может подходить не для всех систем. Например, если вы уже регулярно делаете переиндексацию, то тогда статистика для переиндексированных объектов может обновляться автоматически и нет никакой необходимости обновлять ее отдельно.
Идея заключается в том, чтобы заставить все подсистемы на сервере работать так, чтобы обновить столько объектов статистики, сколько максимально возможно в пределах заданного окна обслуживания, в порядке от худших случаев к лучшим. Расчет состоит в том, что процесс можно будет выполнять ночью и по порядку постепенно обработать все индексы и статистические объекты. Если время обслуживания закончилось, процесс остановится и не будет влиять на производительность сервера в дневное время. Когда наступит следующий вечер, он запустится снова, но будет работать сначала над худшими случаями, которые, будем надеяться, будут включать любые объекты, для которых не было времени обновить статистику предыдущей ночью. В больших системах статистику следует обновлять хотя бы раз в несколько ночей, на циклической основе.
Разработка состоит из набора заданий SQL Agent: один из них — «контролер», который запускает и останавливает процесс, а другие — «исполнители», которые осуществляют обновление в коллекциях индексов. Контролер определяет очередь объектов для обновления, а исполнители выбирают элементы из этой очереди, пока те не кончатся или пока контролер не остановит процесс в конце временного окна обслуживания.
Временные таблицы против табличных переменных и их воздействие на производительность SQL Server
Не существует универсального правила для того, когда и как использовать временные таблицы или табличные переменные. Попробуйте оба варианта и поэкспериментируйте.
Существует три главных теоретических различия между временными таблицами:
create table #T (…)
и табличными переменными:
declare @T table (…)
Первое различие — для табличных переменных не ведутся журналы транзакций. Таким образом, эти переменные находятся вне области действия механизма транзакций, что ясно видно из следующего примера:
create table #T (s varchar(128))
declare @T table (s varchar(128))
insert into #T select 'old value #'
insert into @T select 'old value @'
begin transaction
update #T set s = 'new value #'
update @T set s = 'new value @'
rollback transaction
select * from #T
select * from @T
s
---------------
old value #
s
---------------
new value @
После объявления временной таблицы #T и табличной переменной @T мы присваиваем каждой одинаковую строку «old value» («старое значение»). Затем мы начинаем транзакцию, которая изменяет их содержимое. После этого обе будут содержать одинаковую строку «new value» («новое значение»). Но когда мы откатываем транзакцию, как вы можете видеть, табличная переменная @T сохраняет свое значение, вместо того чтобы вернуться обратно к строке «old value». Это произошло потому, что хотя табличная переменная и была модифицирована внутри транзакции, она не являлась частью самой транзакции.
Второе главное различие — любая процедура с временной таблицей не может быть предварительно скомпилирована, в то время как план выполнения процедур с табличными переменными может быть статически скомпилирован заранее. Предварительная компиляция скрипта дает значительное преимущество в скорости его выполнения. Это преимущество может стать решающим для длинных процедур, где перекомпиляция может оказаться слишком дорогостоящей.
Наконец — табличные переменные существуют только в той же области действия, что и переменные. В отличие от временных таблиц, они не видны во внутренних хранимых процедурах и в выражениях exec(строка). Также они не могут быть использованы в директиве insert/exec.
Зашифрованные поля и производительность SQL Server
По правовым причинам очень важно шифровать поля таблицы с секретными данными, такими как SSN. SQL Server 2005 позволяет вам шифровать данные при помощи различных алгоритмов с использованием симметричных и асимметричных ключей. Также вы можете использовать шифрование, основанное на пароле (этот пароль должен быть предоставлен клиентом для того, чтобы зашифровать/расшифровать данные).
Но все на свете имеет свою цену, поэтому мы хотим знать, сколько это стоит.
Получаем максимум от панели производительности SQL Server 2005
Если вы уже довольно продолжительное время используете SQL Server 2005, то можете спросить, что же я имею в виду, когда ссылаюсь на панель производительности SQL Server 2005. Нет, вы не страдаете от сверхурочной работы или болезни, которая заставила вас выжить из ума и забыть, какие новые возможности были включены в SQL Server 2005. Панель производительности SQL Server 2005 — это новое добавление, которое стало доступно вскоре после выхода SP2 для SQL Server 2005.
Коротко говоря, панель SQL Server 2005 — это пользовательский отчет для Management Studio (пользовательские отчеты — это новая возможность из SP2), который собирает данные из многих динамических представлений управления и динамических функций управления, доступных в SQL Server 2005. Это не замена других инструментов производительности, но вспомогательный инструмент для помощи АБД в определении и устранении проблем производительности. Отчеты панели SQL Server 2005 во многом похожи на многие встроенные отчеты, которые уже предоставляются Management Studio.
Поскольку панель производительности SQL Server 2005 представляет собой дополнительный инструмент, вы должны потратить некоторое время на то, чтобы загрузить этот бесплатный инструмент с вебсайта Microsoft и установить его. К счастью, это достаточно легкий процесс, и я бы крайне рекомендовал всем АБД загрузить и установить панель производительности на каждый экземпляр SQL Server 2005, где установлен SP2.
Где взять панель производительности для SQL Server 2005?
Чтобы установить панель SQL Server 2005, вы должны загрузить с сайта Microsoft по крайней мере два файла. Вопервых, если вы еще этого не сделали, вы должны загрузить SP2 для SQL Server 2005. Это изза того, что SP2 включает новый функционал, который был добавлен для поддержки панели производительности.
Вы можете загрузить SQL Server 2005 Service Pack 2 с www.microsoft.com/technet/prodtechnol/sql/2005/downloads.
Вы можете загрузить дополнение панели производительности SQL Server 2005 с www.microsoft.com/downloads.
...
Чего же вы ждете?
К этому времени вы должны были уже скачать панель производительности. Если еще нет, то чего вы ждете? Это бесплатный инструмент, который может помочь вам лучше справляться с мониторингом производительности и устранением неполадок на ваших серверах SQL. У этого инструмента нет ни одного недостатка, и он будет становиться лучше, по мере того как Microsoft продолжит совершенствовать его.