Криптосервисы .NET Framework (Tjnhmkvyjfnvd QNET Framework)

Перейти к навигации Перейти к поиску

.NET Framework включает набор криптографических сервисов, расширяющих аналогичные сервисы Windows через CryptoAPI. Пространство имен System.Security.Cryptography открывает программный доступ к самым разнообразным криптографическим сервисам, с помощью которых приложения могут шифровать и дешифровать данные, обеспечивать их целостность, а также обрабатывать цифровые подписи и сертификаты.

Пространство имен Cryptography

[править | править код]

На самом высоком уровне пространство имен Cryptography можно разбить на четыре основные части (табл. 1). Главное предназначение этого пространства — предоставлять классы с алгоритмами таких операций, как шифрование и создание хешей. Эти алгоритмы реализуются на основе расширяемого шаблона (pattern), включающего два уровня наследования.

На вершине иерархии располагается абстрактный базовый класс (вроде AsymmetricAlgorithm или HashAlgorithm), имя которого соответствует типу алгоритма. От такого класса наследует абстрактный класс второго уровня, предоставляющий открытый интерфейс для использования данного алгоритма. Например, SHA1 (Secure Hash Algorithm) представляет собой производный от HashAlgorithm класс и содержит методы и свойства, специфичные для алгоритма SHA1. Наконец, сама реализация алгоритма является производной от класса второго уровня; именно её экземпляр создается и используется клиентским приложением. На этом уровне реализация может быть управляемой, неуправляемой или и той и другой.

Элемент Описание
Алгоритмы шифрования Набор классов, применяемых для реализации алгоритмов симметричного и асимметричного шифрования, а также хеширования
Вспомогательные классы Классы, обеспечивающие генерацию случайных чисел, выполнение преобразований, взаимодействие с хранилищем CryptoAPI и само шифрование на основе потоковой модели
Сертификаты Х.509 Классы, определённые в пространстве имен System.Security.Сryptographу. Х509Certificates и представляющие цифровые сертификаты
Цифровые подписи XML Классы, определённые в пространстве имен System.Cryptography.Xml и представляющие цифровые подписи в XML-документах

Табл. 1. Основные элементы пространства имен Cryptography

К именам неуправляемых реализаций обычно добавляется суффикс «CryptoServiceProvider» (скажем, SHA1CryptoServiceProvider), указывающий на то, что данная реализация на самом деле предоставляется криптопровайдером (Cryptographic Service Provider, CSP), который установлен на уровне операционной системы и действует как оболочка CryptoAPI.

В имена управляемых реализаций включается суффикс «Managed» (например SHA1Managed). Такие реализации не опираются на CryptoAPI и содержат исключительно управляемый код.

При создании экземпляра одного из конкретных классов исходные конструкторы всегда записывают в параметры объекта разумные и безопасные значения (если это возможно). Так, алгоритмы асимметричного шифрования, опирающиеся на криптографию с открытым ключом, генерируют случайную пару ключей, а алгоритмы симметричного шифрования — случайный ключ и вектор инициализации(initialization vector, IV); при этом они автоматически настраивают такие свойства, как Mode и Padding. Более того, алгоритмы второго типа по умолчанию стараются использовать «стойкие» значения.

Второй основной набор классов в пространстве имен System.Security.Cryptography включает как классы, реально применяемые в процессе шифрования и расшифровки данных, так и разнообразные вспомогательные классы. Это пространство имен содержит, например, абстрактный класс RandomNumberGenerator, от которого наследуют классы RNGCryptoServiceProvider, ToBase64Transform и FromBase64Transform (используются при соответствующих преобразованиях данных).

Пространство имен Cryptography не только предоставляет алгоритмы шифрования, но и содержит дочернее пространство имен Х509Certificates. Последнее объединяет всего три класса, предназначенных для операций с сертификатами Authenticode X.509 v.3. Класс X509Certificate предоставляет статические методы CreateFromCertFile и CreateFromSignedFile для создания экземпляра сертификата:

X509Certificate с = X509Certificate.CreateFromCertFile(«myCert.cer»);
Console.WriteLine(c.GetName);
Console.WriteLine(c.GetPublicKeyString);
Console.WriteLine(c.GetSerialNumberString);
Console.WriteLine(c.GetExpirationDateString);

В пространстве имен Cryptography также присутствует дочернее пространство имен XML, используемое системой защиты .NET Framework для цифровой подписи XML-объектов в соответствии с проектом WSC-спецификации по синтаксису и обработке XML-подписей (http://www.w3.org/TR/2000/WD-xmldsig-core-20000228/).

Алгоритмы шифрования

[править | править код]

Симметричные алгоритмы

[править | править код]

Есть несколько способов формирования блочных шифров. Наиболее простой и интуитивно понятный способ состоит в том, чтобы разбить исходный текст на блоки соответствующего размера, а затем отдельно каждый блок подвергнуть шифрующему преобразованию. Такой режим использования блочных шифров называют электронной кодовой книгой (ECB — electronic codebook). Его главный недостаток состоит в том, что одинаковые блоки исходного текста при шифровании дадут одинаковые блоки шифр-текста, а это может существенно облегчить противнику задачу взлома. Поэтому режим ECB не рекомендуется использовать при шифровании текстов, по длине превышающих один блок. В таких случаях лучше воспользоваться одним из режимов, связывающих различные блоки между собой.

По умолчанию в CryptoAPI блочные шифры используются в режиме сцепления блоков шифр-текста (CBC — cipher block chaining). В этом режиме при шифровании очередной блок исходного текста вначале комбинируется с предыдущим блоком шифр-текста (при помощи побитового исключающего ИЛИ), а затем полученная последовательность битов поступает на вход блочного шифра. Образующийся на выходе блок шифр-текста используется для шифрования следующего блока. Самый первый блок исходного текста также должен быть скомбинирован с некоторой последовательностью битов, но «предыдущего блока шифр-текста» ещё нет; поэтому режимы шифрования с обратной связью требуют использования ещё одного параметра — он называется инициализирующим вектором (IV — initialization vector). IV — несекретное двоичное значение, размер которого равен длине блока шифра. Чтобы сгенерировать новый ключ, нужно вызвать метод GenerateKey, а для вектора инициализации — метод GenerateIV. Например, для алгоритма RC2, поддерживаемого базовым криптопровайдером Microsoft, размер блока составляет 64 бита (8 байтов).

DESCryptoServiceProvider mDES;
mDES = new DESCryptoServiceProvider();

// Генерируем новый ключ и IV случайным образом
mDES.GenerateKey();
mDES.GenerateIV();

SymmetricAlgorithm
|— AES
|      |— AESCryptoServiceProvider
|      |— AESManaged
|— DES
|      |— DESCryptoServiceProvider
|— RC2
|      |— RC2CryptoServiceProvider
|— Rijndael
|      |— RijndaelManaged
|— TripleDES
|      |— TripieDESCryptoServiceProvider
Иерархия симметричных алгоритмов

SymmetricAlgorithm является абстрактным базовым классом, от которого наследуют другие классы, специфичные для конкретных алгоритмов. К числу поддерживаемых симметричных алгоритмов относятся Data Encryption Standard (DES), RC2, Rijndael, Advanced Encryption Standard (AES) и Triple Data Encryption Standard (TripleDES). Каждый алгоритм включает какой-нибудь производный от SymmetricAlgorithm абстрактный класс вроде DES и производный от базового управляемый класс или класс провайдера сервиса, например DESCryptoServiceProvider. Свойства KeySize и BlockSize позволяют определять длину ключа и размер блока данных (в битах), который может быть зашифрован или расшифрован за одну операцию.

Применение класса RijndaelManaged:

RijndaelManaged oEnc = new RijndaelManaged();
int i;

String strKey = String.Empty;
String strlV = String.Empty;

for(i = 0; i < (oEnc.KeySize / 8); i++)
strKey += oEnc.Key(i).ToString() + " ";

for(i = 0; i < (oEnc.BlockSize / 8); i++)
strlV += oEnc.lV(i).ToString() + " ";

Console.WriteLine(strKey);
Console.WriteLine(strIV);
Console.WriteLine(oEnc.KeySize.Tostring());
Console.WriteLine(oEnc.BlockSize.Tostring());

.NET Framework поддерживает модель программирования на основе потоков (streams). Классы потоков, производные от System.lO.Stream, представляют данные из различных хранилищ (текстовых файлов, XML-документов, MSMQ-сообщений, памяти и сети) и позволяют считывать данные из соответствующих хранилищ или записывать в них. В основе этой функциональности лежит класс CryptoStream, производный от System.IO.Stream и служащий в качестве модели потоков при криптографических преобразованиях.

DESCryptoServiceProvider mDES = new DESCryptoServiceProvider();
FileStream fsOutput = new FileStream(«temp.dat», FileMode.Create, FileAccess.Write);
Byte[] arInput = new Byte[320];
//…

// Создаем DES Encryptor из этого экземпляра 
ICryptoTransform desEncript = mDES.CreateEncryptor();
// Создаем CryptoStream, преобразующий файловый поток
// с применением DES-шифрования
CryptoStream sCrypto = new CryptoStream(fsOutput, desEncrypt, CryptoStreamMode.Write);
// Записываем зашифрованный файл
sCrypto.Write(arInput, 0, arInput.length);
sCrypto.Close();
fsOutput.Close();

Асимметричное шифрование применяется для шифрования небольших объёмов данных, поэтому CryptoStream при асимметричном шифровании не используется.

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

[править | править код]

К общеизвестным асимметричным алгоритмам относятся Digital Signature Algorithm (DSA) и RSA. Эти алгоритмы в конечном счете являются производными от абстрактных классов DSA и RSA, в свою очередь производных от AsymmetricAlgorithm. Так как эти алгоритмы очень сложны, им нужны вспомогательные классы, производные, например, от AsymmetricKeyExchangeFormatter и AsymmetricSignatureFormatter.

AsymmetricAlgorithm
|— DSA
|      |— DSACryptoServiceProvider
|— RSA
|      |— RSACryptoServiceProvider

AsymmetricKeyExchangeFormatter
|— RSAOAEPKeyExchangeFormatter
|— RSAPKCS1KeyExchangeFormatter

AsymmetricKeyExchangeDeformatter
|— RSAOAEPKeyExchangeDeformatter
|— RSAPKCS1KeyExchangeDeformatter

AsymmetricKeySignatureFormatter
|— RSAOAEPSignatureFormatter
|— RSAPKCS1SignatureFormatter

AsymmetricSignatureDeformatter
|— RSAOAEPSignatureDeformatter
|— RSAPKCS1SignatureDeformatter
Иерархия Асимметричных алгоритмов

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

CspParameters cp = new CspParameters();
cp.KeyContainerName = ContainerName;
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(cp);

Обмен симметричными ключами

[править | править код]

За обмен сессионными ключами в .NET отвечают классы RSAOAEPKeyExchangeFormatter/Deformatter и RSAPKCS1KeyExchangeFormatter/Deformatter. Они унаследованы от базовых классов AsymmetricKeyExchangeFormatter/Deformatter, предоставляющих методы CreateKeyExchange и DecryptKeyExchange для шифрования и дешифрации сессионных ключей, соответственно.

RSACryptoServiceProvider rsa1 = new RSACryptoServiceProvider(1024); // получатель ключа
RSAParameters rp = rsa1.ExportParameters(false);
Console.WriteLine(«Passing public key to sender…»);
// передаем открытый ключ отправителю
//…

RSACryptoServiceProvider rsa2 = new RSACryptoServiceProvider(1024); // отправитель ключа
Console.WriteLine(«Importing receiver’s public key…»);
// импортируем открытый ключ получателя
rsa2.ImportParameters(rp);
AsymmetricKeyExchangeFormatter kf = (AsymmetricKeyExchangeFormatter) new RSAOAEPKeyExchangeFormatter(rsa2);
byte[] key = new Byte[16]; // 128-битный ключ
byte[] enckey = kf.CreateKeyExchange(key);
Console.WriteLine(«Sending encrypted session key to receiver…»);
// передаем зашифрованный сессионный ключ получателю
//…

AsymmetricKeyExchangeDeformatter kd = (AsymmetricKeyExchangeDeformatter) new RSAOAEPKeyExchangeDeformatter(rsa1);
// Расшифровываем ключ
byte[] deckey = kd.DecryptKeyExchange(enckey);
for(int i = 0; i < 16; i++)
if (deckey[i] != key[i])
{
Console.WriteLine(«Key exchange failed»);
}
Console.WriteLine(«Key exchange succeeded»);

Хэширующие алгоритмы

[править | править код]

Пространство имен Cryptography содержит базовый класс HashAlgorithm и производные классы, поддерживающие алгоритмы MD5, SHA1, SHA256, SHA384 и SHA512. Алгоритм MD5 дает 128 битный хеш, a SHA1 — 160 битный. Числа в названиях других версий SHA-алгоритмов соответствуют длине создаваемых ими хешей. Чем больше хеш, тем надежнее алгоритм и тем труднее его взломать. Все эти алгоритмы реализованы в двух версиях: на основе управляемого и неуправляемого кода.

HashAlqorithm
|— KeyedHashAlgorithm
|      |— HMACSHA1
|      |— MACTripleDES
|— MD5
|      |— MD5CryptoServiceProvider
|— SHA1
|      |— SHA1CryptoServiceProvider
|      |— SHA1Managed
|— SHA256
|      |— SHA256Managed
|— SHA384
|      |— SHA384Managed
|— SHA512
|      |— SHA512Managed
Иерархия хеширующих алгоритмов

Чтобы вычислить дайджест, нужно просто создать экземпляр класса алгоритма хеширования и вызвать его перегруженный метод ComputeHash, наследуемый от HashAlgorithm:

FileStream fsData = new FileStream(«mydata.txt»,FileHode.Open, FileAccess.Read);
Byte[] digest;
SHA512Managed oSHA = new SHA512Managed(digest  oSHA.ComputeHash(fsData));
fsKey.Close()

Здесь методу ComputeHash передается объект Stream, но он принимает и байтовый массив. В пространстве имен Cryptography также имеется абстрактный класс KeyedHashAlgorithm. Алгоритмы, реализованные в классах HMACSHA1 и MACTripleDES, производных от KeyedHashAlgorithm, позволяют генерировать Message Authentication Code (MAC). С помощью MAC можно определить, были ли модифицированы данные, переданные по незащищенному каналу связи, — при условии, что и отправитель, и получатель используют общий секретный ключ.

Цифровая подпись

[править | править код]

Метод SignHash классов RSACryptoServiceProvider и DSACryptoServiceProvider вычисляет подпись для созданного по специальному алгоритму хеша данных. Алгоритм хеширования передается в качестве второго параметра в виде идентификатора, который может быть вычислен с помощью функции MapNameToOID. Для RSACryptoServiceProvider это SHA1 и MD5, а для DSACryptoServiceProvider — только SHA1.

rsaCSP.SignHash(hashedData, CryptoConfig.MapNameToOID(«SHA1»));

Классы RSAPKCS1SignatureFormatter/Deformatter и DSASignatureFormatter/Deformatter создают цифровую подпись. Обе пары классов унаследованы от классов AsymmetricSignatureFormatter/Deformatter, предоставляющих стандартный интерфейс создания и верификации цифровой подписи — методы CreateSignature и VerifySignature. Перед вычислением или проверкой цифровой подписи нужно обязательно установить алгоритм хеширования, который будет использоваться в процессе работы, с помощью вызова SetHashAlgorithm. RSAPKCS1SignatureFormatter понимает два алгоритма хеширования — MD5 и SHA1, а DSASignatureFormatter — только SHA1.

// создание цифровой подписи RSA
AsymmetricSignatureFormatter sf;
sf = (AsymmetricSignatureFormatter) new RSAPKCS1SignatureFormatter(rsa); // создаем форматер
sf.SetHashAlgorithm(«MD5»); // выбираем алгоритм хеширования
sig = sf.CreateSignature(Hash); // создаем подпись (хеш должен быть уже посчитан ранее)

//проверка цифровой подписи RSA
AsymmetricSignatureDeformatter df;
df = (AsymmetricSignatureDeformatter) new RSAPKCS1SignatureDeformatter(rsa); // создаем деформатер
df.SetHashAlgorithm(«MD5»);
if (df.VerifySignature(Hash, sig)) // проверяем подпись
{
// подпись верна
}
else
{
// подпись неверна
}

Примечания

[править | править код]

Литература

[править | править код]
  • Ю. Е. Купцевич. Альманах программиста, том 4. Безопасность в Microsoft .NET. — М.: Издательско-торговый дом «Русская Редакция», 2004. — 304 с. — ISBN 5–7502–0184–8.