Поделиться через


Общие сведения о криптографии

Обновлен: Ноябрь 2007

Использование криптографии обеспечивает защиту данных от просмотра или изменения, а также создает защищенные каналы связи на основе незащищенных каналов. Например, данные могут быть зашифрованы с помощью некоторого криптографического алгоритма, переданы в зашифрованном виде, а затем расшифрованы лицом, которому они предназначались. Если зашифрованные данные будут перехвачены третьим лицом, расшифровать их будет трудно.

В рамках данного обзора вкратце рассматриваются методы и способы шифрования, поддерживаемые .NET Framework, включая манифесты ClickOnce, пакет B и поддержку криптографии следующего поколения (CNG), обеспечиваемую .NET Framework, версия 3.5. Обзор включает следующие разделы.

  • Криптографические примитивы

  • Шифрование с закрытым ключом

  • Шифрование с открытым ключом

  • Цифровые подписи

  • Хэш-коды

  • Генерация случайных чисел

  • Манифест ClickOnce

  • Поддержка пакета B

  • Классы криптографии следующего поколения (CNG)

Дополнительные сведения о шифровании, а также службах, компонентах и средствах корпорации Майкрософт, позволяющих обеспечить криптографическую защиту в приложениях, см. в разделе данной документации, посвященном обеспечению безопасности при разработке приложений Win32 и COM.

Криптографические примитивы

В типичной ситуации, когда используется криптография, две стороны (Алиса и Боб) осуществляют связь по незащищенному каналу. Алиса и Боб хотят быть уверены, что передаваемые ими данные не могут быть прочитаны даже в случае возможного перехвата. Более того, поскольку Алиса и Боб находятся в удаленных друг от друга местах, Алиса должна быть уверена, что информация, которую она получает от Боба, не подвергается изменению во время передачи. Также она должны быть уверена, что получаемые ею данные действительно исходят от Боба, а не от кого-то, выдающего себя за Боба.

Криптография используется для достижения следующих целей.

  • Конфиденциальность: защита данных или личной информации пользователя от несанкционированного просмотра.

  • Целостность данных: защита данных от несанкционированного изменения.

  • Проверка подлинности: проверка того, что данные исходят действительно от определенного лица.

  • Неотрекаемость. Ни одна сторона не должна иметь возможность отрицать факт отправки сообщения.

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

Криптографический примитив

Применение

Шифрование с закрытым ключом (симметричное шифрование)

Осуществляет преобразование данных с целью предотвращения их просмотра третьей стороной. В данном способе шифрования для шифрования и расшифровки данных используется один общий закрытый ключ.

Шифрование с открытым ключом (асимметричное шифрование)

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

Создание криптографической подписи

Позволяет проверить, что данные действительно исходят от конкретного лица, используя для этого уникальную цифровую подпись этого лица. Данный процесс также использует хэш-функции.

Криптографическое хэширование

Отображает данные любого размера в байтовую последовательность фиксированной длины. Результаты хэширования статистически уникальны; отличающаяся хотя бы одним байтом последовательность не будет преобразована в то же самое значение.

Шифрование с закрытым ключом

При шифровании с закрытым ключом для шифровки и дешифровки данных используется один закрытый ключ. Необходимо обезопасить этот ключ от несанкционированного доступа, потому что любое обладающее им лицо может использовать его для расшифровки данных или шифрования собственных данных с подменой источника.

Шифрование с закрытым ключом называют также симметричным шифрованием, так как для шифрования и расшифровки используется один и тот же ключ. Алгоритмы шифрования с закрытым ключом являются очень быстрыми (по сравнению с алгоритмами шифрования с открытым ключом) и хорошо подходят для осуществления криптографических преобразований больших массивов информации. Асимметричные алгоритмы шифрования, такие как RSA, имеют математические ограничения на объем шифруемых данных. Для симметричных алгоритмов шифрования подобные проблемы обычно не возникают.

Разновидность алгоритмов шифрования с закрытым ключом, называемая блочным шифром, используется для шифрования целого блока данных за один раз. Блочные шифры (такие как DES, TrippleDES и AES) преобразуют входной блок данных длиной в n байтов в выходной блок зашифрованных данных. Если необходимо зашифровать или расшифровать последовательность байтов, следует делать это блок за блоком. Поскольку n достаточно мало (8 байт для DES и TripleDES; 16 байт [по умолчанию], 24 или 32 байта для AES), данные большей длины, чем n, должны шифроваться блоками, один блок за раз. Блоки данных размером менее n байт должны быть увеличены до n байт перед обработкой.

Одна из простейших форм блочного шифра называется режимом электронной кодовой книги (ECB). Режим ECB не считается безопасным, поскольку в нем не используется вектор инициализации для инициализации первого текстового блока. Для заданного закрытого ключа k простой блочный шифр, не использующий вектор инициализации, зашифрует одинаковые входные блоки текста в одинаковые выходные блоки зашифрованного текста. Поэтому если во входном текстовом потоке присутствуют одинаковые блоки, в зашифрованном потоке также будут присутствовать одинаковые блоки. Такие повторяющиеся выходные блоки сообщают неправомочным пользователям о ненадежных алгоритмах шифрования, которыми можно воспользоваться, о и возможных типах атак. Шифр ECB поэтому очень уязвим для анализа и, в конечном итоге, взлому ключа.

Классы блочных шифров, предоставляемые библиотекой базовых классов, используют режим сцепления, называемый сцеплением шифровальных блоков (CBC), хотя данную настройку по умолчанию можно изменить.

Шифры CBC решают проблемы, связанные с использованием шифров ECB, благодаря использованию вектора инициализации (IV) для шифрования первого текстового блока. Перед шифрованием каждого блока открытого текста он объединяется с зашифрованным текстом предыдущего блока с помощью поразрядной исключающей операции OR (XOR). Поэтому каждый блок зашифрованного текста зависит от всех предыдущих блоков. При использовании этой системы шифрования стандартные заголовки сообщений, которые могут быть известны неправомочному пользователю, не могут быть использованы им для восстановления закрытого ключа.

Одним из способов раскрытия данных, зашифрованных с помощью шифра CBC, является подбор ключа методом полного перебора возможных ключей. В зависимости от длины использованного для шифрования ключа, такой подбор занимает очень много времени даже на самых быстрых компьютерах, поэтому он является практически неосуществимым. Шифры с большей длиной ключа труднее взломать. Несмотря на то, что использование шифрования не гарантирует теоретическую невозможность раскрытия зашифрованных данных неправомочным лицом, стоимость такого взлома становится чрезвычайно высокой. Если процесс подбора ключа и раскрытия зашифрованных данных занимает три месяца, в то время как сами данные актуальны в течение всего нескольких дней, подбор ключа методом полного перебора не представляет практической ценности.

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

Предположим, что Алиса и Боб являются двумя сторонами, которые хотят осуществлять связь по незащищенному каналу; они могли бы воспользоваться шифрованием с закрытым ключом следующим образом. Алиса и Боб соглашаются использовать некоторый определенный алгоритм (например, AES) с определенным ключом и вектором инициализации. Алиса пишет сообщение и создает сетевой поток, через который можно отправить это сообщение (например, именованный канал или канал электронной почты). Затем она шифрует текст с помощью ключа и вектора инициализации и по интрасети пересылает зашифрованное сообщение и вектор инициализации Бобу. Боб принимает зашифрованный текст и осуществляет расшифровку, используя ранее согласованные ключ и вектор инициализации. Если происходит перехват передаваемых данных, злоумышленник не может восстановить исходное сообщение, так как ему не известны ключ и вектор инициализации. В этой ситуации в секрете должен сохраняться только ключ. В более реалистичном случае либо Алиса, либо Боб создает закрытый ключ и использует шифрование с открытым ключом (асимметричное) для передачи другой стороне закрытого (симметричного) ключа. Дополнительные сведения о шифровании с открытым ключом см. в следующем разделе.

.NET Framework предоставляет следующие классы, которые реализуют алгоритмы шифрования с закрытым ключом:

  • AesManaged (введен в .NET Framework, версия 3.5).

  • DESCryptoServiceProvider.

  • HMACSHA1 (Технически это алгоритм с закрытым ключом, поскольку он представляет собой код проверки подлинности сообщений, вычисляемый на основе хэш-функции шифрования и закрытого ключа. См. подраздел Хэш-коды, приведенный ниже.

  • RC2CryptoServiceProvider.

  • RijndaelManaged.

  • TripleDESCryptoServiceProvider.

Шифрование с открытым ключом

При шифровании с открытым ключом используются закрытый ключ, который должен храниться в секрете от неправомочных пользователей, а также открытый ключ, который может предоставляться кому угодно. Открытый и закрытый ключи математически взаимосвязаны; данные, зашифрованные с помощью открытого ключа, можно расшифровать исключительно с помощью соответствующего закрытого ключа, а цифровая подпись данных, подписанных с помощью закрытого ключа, может быть проверена только с помощью соответствующего открытого ключа. Открытый ключ может быть предоставлен любому лицу; он используется для шифрования данных, которые должны быть отправлены хранителю закрытого ключа. Алгоритмы шифрования с открытым ключом также известны как асимметричные алгоритмы, потому что для шифрования данных требуется один ключ, а для расшифровки — другой ключ. Основное правило шифрования запрещает повторное использование ключа; оба ключа в каждом сеансе шифрования должны быть уникальными. Однако на практике ассиметричные ключи обычно используются подолгу.

Две стороны (Алиса и Боб) могут использовать шифрование с открытым ключом следующим образом. Сначала Алиса создает набор, состоящий из открытого и закрытого ключей. Если Боб хочет послать Алисе зашифрованное сообщение, он запрашивает у Алисы ее открытый ключ. Алиса высылает Бобу свой открытый ключ через незащищенную сеть, и Боб использует полученный ключ для шифрования своего сообщения. Боб пересылает зашифрованное сообщение Алисе, а она расшифровывает полученные данные с помощью своего закрытого ключа. Если Боб получил ключ Алисы по незащищенному каналу, например через открытую сеть, он оказывается уязвимым для атак типа "злоумышленник в середине". Поэтому Бобу необходимо убедиться, что Алиса имеет правильную копию открытого ключа.

Во время передачи Бобу открытого ключа Алисы может произойти несанкционированный перехват ключа третьим лицом. Более того, возможна ситуация, что то же самое лицо перехватит зашифрованное сообщение Боба. Тем не менее неправомочная сторона не может осуществить расшифровку сообщения с помощью открытого ключа. Сообщение можно расшифровать только с помощью закрытого ключа Алисы, который не передавался через какие-либо системы связи. Алиса не использует свой закрытый ключ для шифрования ответного сообщения Бобу, потому что любое лицо может расшифровать это сообщение с помощью открытого ключа. Если Алиса желает послать Бобу ответное сообщение, она запрашивает у Боба его открытый ключ и шифрует свое сообщение, используя полученный открытый ключ. Затем Боб осуществляет расшифровку сообщения с помощью своего соответствующего закрытого ключа.

В этом случае Алиса и Боб используют шифрование с открытым ключом (асимметричное) для передачи закрытого (симметричного) ключа, а затем пользуются шифрованием с этим закрытым ключом в течение сеанса связи.

В следующем списке сравниваются алгоритмы шифрования с открытым и закрытым ключом.

  • Алгоритмы шифрования с открытым ключом используют буфер фиксированного размера, в то время как алгоритмы шифрования с закрытым ключом могут использовать буфер переменного размера.

  • Алгоритмы шифрования с открытым ключом не могут быть использованы для сцепления блоков данных в потоки тем же образом, как в алгоритмах шифрования с закрытым ключом, потому что можно шифровать только маленькие порции данных. Соответственно, асимметричные операции не используют такую же потоковую модель, как симметричные операции.

  • Шифрование с открытым ключом имеет намного большее пространство ключей (диапазон возможных значений ключа), чем шифрование с закрытым ключом. Поэтому такое шифрование менее уязвимо к атакам полного перебора, когда проверяются все возможные значения ключа.

  • Открытые ключи можно легко распространять, поскольку они не требуют особой защиты при условии, что существует некий способ установления подлинности источника.

  • Некоторые алгоритмы шифрования с открытым ключом (такие как RSA и DSA, но не Diffie-Hellman) могут быть использованы для создания цифровых подписей, служащих для подтверждения идентичности лица, от которого исходят данные.

  • Алгоритмы шифрования с открытым ключом являются весьма медленными (по сравнению с алгоритмами шифрования с закрытым ключом) и не предназначены для шифрования больших объемов данных. Использование шифрования с открытым ключом имеет смысл только при передаче очень малых массивов данных. Обычно шифрование с открытым ключом применяется для того, чтобы зашифровать ключ и вектор инициализации, которые будут использоваться при шифровании с закрытым ключом. После передачи ключа и вектора инициализации используется уже шифрование с закрытым ключом.

.NET Framework предоставляет следующие классы, которые реализуют алгоритмы шифрования с открытым ключом:

RSA допускает как шифрование, так и подписывание, в то время как DSA может использоваться только для подписывания, а Diffie-Hellman — только для генерации ключей. В целом, алгоритмы с открытым ключом имеют более ограниченную сферу применения, чем алгоритмы с закрытым ключом.

Цифровые подписи

Алгоритмы шифрования с открытым ключом могут также использоваться для создания цифровых подписей. Цифровые подписи удостоверяют подлинность источника данных (если вы доверяете открытому ключу источника) и защищают целостность данных. С помощью открытого ключа, созданного Алисой, получатель данных, отправленных Алисой, может проверить, что их источником действительно является Алиса, сравнив цифровую подпись полученных данных с открытым ключом Алисы.

Чтобы использовать шифрование с открытым ключом для создания цифровой подписи сообщения, Алиса сначала применяет к этому сообщению алгоритм хэширования, который создает хэш-функцию сообщения. Хэш-функция сообщения является компактным и уникальным отображением данных. Для создания своей личной цифровой подписи Алиса шифрует хэш-функцию сообщения с помощью своего закрытого ключа. При получении сообщения и цифровой подписи Боб расшифровывает подпись с помощью открытого ключа Алисы, восстанавливая зашифрованную хэш-функцию сообщения, а затем осуществляет хэширование сообщения с помощью того же алгоритма, который использовала Алиса. Если вычисленная Бобом хэш-функция в точности совпадает с хэш-функцией, полученной от Алисы, Боб может быть уверен, что сообщение пришло действительно от владельца закрытого ключа, а также в том, что данные в сообщении не подвергались модификациям. Если Боб уверен, что именно Алиса владеет закрытым ключом, он удостоверяется, что сообщение пришло от Алисы.

92f9ye3s.alert_note(ru-ru,VS.90).gifПримечание.

Цифровая подпись может быть проверена любым лицом, потому что открытый ключ источника данных является общедоступным и обычно включается в формат цифровой подписи. Рассматриваемый метод не обеспечивает секретности сообщения; для обеспечения секретности его следует еще и зашифровать.

.NET Framework предоставляет следующие классы, реализующие алгоритмы создания цифровой подписи.

Хэш-коды

Алгоритмы хэширования преобразуют двоичные последовательности произвольной длины в двоичные последовательности фиксированного меньшего размера, известные как хэш-коды. Хэш-код является числовым представлением порции данных. Если осуществляется хэширование абзаца текста и в нем изменяется хотя бы одна буква, результат хэширования изменится. Если хэш является криптостойким, его код значительно изменится. Например, если изменяется один бит сообщения, результат выполнения криптостойкой хэш-функции может отличаться на 50%. Несколько входных значений могут преобразовываться в один хэш-код. Однако в вычислительном плане немыслимо найти два разных входных набора данных, результаты хэширования которых полностью совпадают.

Две стороны (Алиса и Боб) могут использовать хэш-функцию для проверки целостности сообщений. Им нужно выбрать хэш-алгоритм для подписывания сообщений. Алиса будет писать сообщение, а затем создавать хэш этого сообщения с помощью выбранного алгоритма. Затем стороны могут применять один из следующих вариантов дальнейших действий.

  • Алиса отправляет Бобу сообщение с открытым текстом и хэш сообщения (цифровую подпись). Боб получает сообщение, применяет к нему хэш-алгоритм и сравнивает свое значение хэша со значением, полученным от Алисы. Если хэш-коды совпадают, значит, данные не изменялись. Если хэш-коды не совпадают, значит, данные изменялись после создания.

    К сожалению, этот способ не позволяет установить подлинность отправителя. Любой человек может выдавать себя за Алису и отправлять сообщения Бобу. Для этого достаточно подписывать сообщения с помощью такого же хэш-алгоритма, и Боб сможет лишь проверить, что сообщение соответствует подписи. Это одна из форм атаки "злоумышленник в середине". Дополнительные сведения см. в разделе Пример защищенного обмена данными с шифрованием CNG.

  • Алиса отправляет Бобу сообщение с открытым текстом по незащищенному открытому каналу. По защищенному закрытому каналу она оправляет Бобу хэш сообщения. Боб получает сообщение с открытым текстом, хэширует его и сравнивает хэш со значением, полученным по закрытому каналу. Если хэши совпадают, Боб может сделать два вывода:

    • сообщение не было изменено;

    • отправитель сообщения подлинный (Алиса).

    Для того чтобы такая система работала, Алиса должна скрывать оригинальный хэш-код от всех, кроме Боба.

  • Алиса по незащищенному открытому каналу отправляет Бобу сообщение в виде открытого текста, а хэш сообщения помещает на свой общедоступный веб-узел.

    Такой подход позволяет защититься от изменения хэша третьей стороной. Хотя сообщение и его хэш могут видеть все, изменить хэш может только Алиса. Злоумышленнику, который хочет выдать себя за Алису, потребуется доступ к веб-узлу Алисы.

Ни один из описанных выше способов не защищает Алису от чтения ее сообщений третьими лицами, поскольку сообщения передаются в виде открытого текста. Для обеспечения полной защиты обычно требуется использовать цифровые подписи и шифрование.

.NET Framework предоставляет следующие классы, реализующие алгоритмы создания цифровой подписи.

92f9ye3s.alert_note(ru-ru,VS.90).gifПримечание.

Недостатки алгоритма MD5 были выявлены еще в 1996 году, и вместо него был рекомендован алгоритм SHA-1. В 2004 году были обнаружены дополнительные уязвимости, и в настоящее время алгоритм MD5 уже не считается безопасным. Алгоритм SHA-1 также был признан ненадежным, и вместо него рекомендуется использовать SHA-2.

Генерация случайных чисел

Процесс генерации случайных чисел является составной частью многих криптографических операций. Например, криптографические ключи должны выбираться настолько случайно, насколько это возможно, чтобы было фактически невозможно воспроизвести их значения. Криптографические генераторы случайных чисел должны генерировать результат, который нельзя предсказать вычислительными методами с вероятностью хотя бы 50%. Поэтому все методы предсказания очередного случайного бита не должны быть точнее, чем простое угадывание. Классы .NET Framework используют генераторы случайных чисел для создания криптографических ключей.

Класс RNGCryptoServiceProvider является реализацией алгоритма генерации случайных чисел.

Манифест ClickOnce

В .NET Framework 3.5 следующие криптографические классы используются проверки и получения сведений о подписях манифестов для приложений, которые развертываются с применением технологии ClickOnce.

Кроме того, следующие классы предоставляют сведения о конкретных подписях:

  • StrongNameSignatureInformation содержит сведения о строгом имени подписи для манифеста.

  • AuthenticodeSignatureInformation представляет сведения о подписи Authenticode для манифеста.

  • TimestampInformation содержит сведения об отметке времени на подписи Authenticode.

  • TrustStatus предоставляет простой способ проверить, является ли подпись Authenticode достоверной.

Поддержка пакета B

Платформа .NET Framework 3.5 поддерживает набор криптографических алгоритмов пакета B, опубликованных национальным агентством по безопасности (NSA). Дополнительные сведения о пакете B см. в документе NSA Suite B Cryptography Fact Sheet.

Включены следующие алгоритмы.

  • Дополнительный стандарт шифрования Advanced Encryption Standart (AES) с размером ключа для шифрования от 128 до 256 битов.

  • Алгоритмы SHA-1, SHA-256, SHA-384 и SHA-512 для хеширования. (Последние три обычно объединяются и известны как SHA-2.)

  • Алгоритм цифровой подписи ECDSA, использующий кривые в 256, 384 и 521 битов для подписи. В документации NSA приводится определение этих кривых, которые называются в соответствии с ней P-256, P-384 и P-521. Этот алгоритм предоставляется в классе ECDsaCng. Он позволяет отмечать закрытым ключом и проверять подпись открытым ключом.

  • Алгоритм ECDH, использующий кривые в 256, 384 и 521 битов для обмена ключами/тайного соглашения. Этот алгоритм предоставляется в классе ECDiffieHellmanCng.

Оболочки управляемого кода для сертифицированных Федеральным стандартом обработки информации (FIPS) реализаций AES, SHA-256, SHA-384 и SHA-512 доступны в новых классах AesCryptoServiceProvider, SHA256CryptoServiceProvider, SHA384CryptoServiceProvider и SHA512CryptoServiceProvider.

Классы криптографии следующего поколения (CNG)

Классы криптографии следующего поколения (CNG) предоставляют управляемую оболочку для собственных функций CNG. (CNG является заменой CryptoAPI.) В имена этих классов входит подстрока "Cng". Центральным в группе классов оболочек CNG является класс контейнера ключей CngKey, который абстрагирует хранение и использование CNG ключей. Этот класс позволяет безопасно хранить пару ключей или открытый ключ и ссылаться на него, используя простое строковое имя. Класс цифровых подписей ECDsaCng и класс шифрования ECDiffieHellmanCng на основе эллиптических кривых используют объекты CngKey.

Класс CngKey используется для множества дополнительных операций, включая открытие, создание, удаление и экспорт ключей. Он также предоставляет доступ к базовому ключу дескриптора, используемому при непосредственном вызове собственных функций.

.NET Framework 3.5 также включает множество вспомогательных классов CNG, некоторые из которых приведены ниже.

  • CngProvider поддерживает поставщик хранилища ключей.

  • CngAlgorithm поддерживает алгоритм CNG.

  • CngProperty поддерживает часто используемые свойства ключей.

См. также

Основные понятия

Модель криптографии .NET Framework

Пример защищенного обмена данными с шифрованием CNG

Другие ресурсы

Задачи криптографии

Службы криптографии