Класс формирования данных для обмена симметричным ключом на основе ГОСТ Р 34.10 транспорта.

Пространство имен:  CryptoPro.Sharpei
Сборка:  CryptoPro.Sharpei.Base (в CryptoPro.Sharpei.Base.dll)

Синтаксис

Visual Basic
<ComVisibleAttribute(True)> _
Public Class Gost2012_256KeyExchangeFormatter _
	Inherits AsymmetricKeyExchangeFormatter
C#
[ComVisibleAttribute(true)]
public class Gost2012_256KeyExchangeFormatter : AsymmetricKeyExchangeFormatter
Visual C++
[ComVisibleAttribute(true)]
public ref class Gost2012_256KeyExchangeFormatter : public AsymmetricKeyExchangeFormatter
JavaScript
CryptoPro.Sharpei.Gost2012_256KeyExchangeFormatter = function();

Type.createClass(
	'CryptoPro.Sharpei.Gost2012_256KeyExchangeFormatter',
	AsymmetricKeyExchangeFormatter);

Заметки

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

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

Для получения данных обмена ключами и извлечения соответствующего симметричного ключа служит класс Gost2012_256KeyExchangeDeformatter.

Примеры

Пример работы с форматтером и деформаттером обмена ключами.
C# Copy imageCopy Code
// Copyright (C) 2006-2012 Крипто-Про. Все права защищены.
//
// Этот файл содержит информацию, являющуюся
// собственностью компании Крипто-Про.
// 
// Любая часть этого файла не может быть скопирована,
// исправлена, переведена на другие языки,
// локализована или модифицирована любым способом,
// откомпилирована, передана по сети с или на
// любую компьютерную систему без предварительного
// заключения соглашения с компанией Крипто-Про.
// 
// Программный код, содержащийся в этом файле, предназначен
// исключительно для целей обучения и не может быть использован
// для защиты информации.
// 
// Компания Крипто-Про не несет никакой
// ответственности за функционирование этого кода.

// Пример передачи сессионного ключа.
// 
// Данный пример:
// 1. Создает случайный ключ получателя.
// 2. Создает случайный сессионный симметричный ключ.
// 3. Шифрует на сессионном ключе сообщение.
// 4. Шифрует сессионный ключ на ключе получателя.
// 5. Расшифровывает сессионный ключ и сообщение.

using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
using System.Security.Cryptography;

using CryptoPro.Sharpei;

namespace Samples.MySamples
{
    class KeyExchange2012_256
    {
        // Ассиметричный ключ получателя.
        private Gost3410_2012_256 AssymKey;
        // Синхропосылка.
        private byte[] IV;

        [STAThread]
        static void Main(string[] args)
        {
            // Создаем случайный открытый ключ.
            KeyExchange2012_256 GostKeyExchange = new KeyExchange2012_256();
            Gost3410_2012_256 gkey = new Gost3410_2012_256CryptoServiceProvider();
            GostKeyExchange.InitializeKey(gkey);

            // Создаем случайный секретный ключ, который необходимо передать.
            Gost28147 key = new Gost28147CryptoServiceProvider();
            // Синхропосылка не входит в GostKeyTransport и должна
            // передаваться отдельно.
            GostKeyExchange.IV = key.IV;

            // Создаем форматтер, шифрующий на ассиметричном ключе получателя.
            Gost2012_256KeyExchangeFormatter Formatter = new Gost2012_256KeyExchangeFormatter(GostKeyExchange.AssymKey);
            // GostKeyTransport - формат зашифрованной для безопасной передачи 
            // ключевой информации.
            GostKeyTransport encKey = Formatter.CreateKeyExchange(key);

            // Шифруемая строка
            string message = "012345678901234567890";
            byte[] sourceBytes = Encoding.ASCII.GetBytes(message);
            Console.WriteLine("** Строка до шифрования: " + message);

            // Шифруем строку на сессионном ключе
            byte[] encBytes = GostKeyExchange.GostEncrypt(key, sourceBytes);
            Console.WriteLine("** Строка после шифрования: " +
                   Encoding.ASCII.GetString(encBytes));

            // Получатель расшифровывает GostKeyTransport и само сообщение.
            byte[] decBytes = GostKeyExchange.GostDecrypt(encKey, encBytes);
            Console.WriteLine("** Строка после расшифрования: " +
                  Encoding.ASCII.GetString(decBytes));

            Console.ReadLine();
        }

        // Создаем ключ получателя.
        private void InitializeKey(Gost3410_2012_256 gkey)
        {
            AssymKey = gkey;
        }

        // Шифруем байтовый массив
        byte[] GostEncrypt(Gost28147 key, byte[] sourceBytes)
        {
            int currentPosition = 0;
            byte[] targetBytes = new byte[1024];
            int sourceByteLength = sourceBytes.Length;

            // Создаем шифратор для ГОСТ.
            CPCryptoAPITransform cryptoTransform = (CPCryptoAPITransform)key.CreateEncryptor();

            // Размер блока считанных байт.
            int inputBlockSize = cryptoTransform.InputBlockSize;

            // Размер выходного блока.
            int outputBlockSize = cryptoTransform.OutputBlockSize;

            try
            {
                // Если возможна обработка нескольких блоков:
                if (cryptoTransform.CanTransformMultipleBlocks)
                {
                    int numBytesRead = 0;
                    while (sourceByteLength - currentPosition >= inputBlockSize)
                    {
                        // Преобразуем байты начиная с currentPosition в массиве 
                        // sourceBytes, записывая результат в массив targetBytes.
                        numBytesRead = cryptoTransform.TransformBlock(
                        sourceBytes, currentPosition,
                        inputBlockSize, targetBytes,
                            currentPosition);
                        currentPosition += numBytesRead;
                    }
                    // Преобразуем последний блок.
                    byte[] finalBytes = cryptoTransform.TransformFinalBlock(
                        sourceBytes, currentPosition,
                        sourceByteLength - currentPosition);

                    // Записываем последний зашифрованный блок 
                    // в массив targetBytes.
                    finalBytes.CopyTo(targetBytes, currentPosition);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Caught unexpected exception:" + ex.ToString());
            }
            // Определяем, может ли CPCryptoAPITransform использоваться повторно.
            if (!cryptoTransform.CanReuseTransform)
            {
                // Освобождаем занятые ресурсы.
                cryptoTransform.Clear();
            }
            // Убираем неиспользуемые байты из массива.
            return TrimArray(targetBytes);
        }

        // Действия получателя - расшифровываем полученные сессионный ключ и сообщение.
        byte[] GostDecrypt(GostKeyTransport encKey, byte[] encBytes)
        {
            // Деформаттер для ключей, зашифрованных на ассиметричном ключе получателя.
            Gost2012_256KeyExchangeDeformatter Deformatter = new Gost2012_256KeyExchangeDeformatter(AssymKey);
            // Получаем ГОСТ-овый ключ из GostKeyTransport.
            Gost28147 key = (Gost28147)Deformatter.DecryptKeyExchange(encKey);
            // Устанавливаем синхропосылку.
            key.IV = IV;
            byte[] targetBytes = new byte[1024];
            int currentPosition = 0;

            // Создаем дешифратор для ГОСТ.
            CPCryptoAPITransform cryptoTransform =
                (CPCryptoAPITransform)key.CreateDecryptor();

            int inputBlockSize = cryptoTransform.InputBlockSize;
            int sourceByteLength = encBytes.Length;

            try
            {
                int numBytesRead = 0;
                while (sourceByteLength - currentPosition >= inputBlockSize)
                {
                    // Преобразуем байты начиная с currentPosition в массиве 
                    // sourceBytes, записывая результат в массив targetBytes.
                    numBytesRead = cryptoTransform.TransformBlock(
                        encBytes,
                        currentPosition,
                        inputBlockSize,
                        targetBytes,
                        currentPosition);

                    currentPosition += numBytesRead;
                }

                // Преобразуем последний блок.
                byte[] finalBytes = cryptoTransform.TransformFinalBlock(
                    encBytes,
                    currentPosition,
                    sourceByteLength - currentPosition);

                // Записываем последний расшифрованный блок 
                // в массив targetBytes.
                finalBytes.CopyTo(targetBytes, currentPosition);
            }
            catch (Exception ex)
            {
                Console.WriteLine("Caught unexpected exception:" + ex.ToString());
            }
            // Убираем неиспользуемые байты из массива.
            return TrimArray(targetBytes);
        }
        private static byte[] TrimArray(byte[] targetArray)
        {
            IEnumerator enum1 = targetArray.GetEnumerator();
            int i = 0;
            while (enum1.MoveNext())
            {
                if (enum1.Current.ToString().Equals("0"))
                {
                    break;
                }
                i++;
            }
            // Создаем новый массив нужного размера.
            byte[] returnedArray = new byte[i];
            for (int j = 0; j < i; j++)
            {
                returnedArray[j] = targetArray[j];
            }
            return returnedArray;
        }
    }
}

Иерархия наследования

System..::..Object
  AsymmetricKeyExchangeFormatter
    CryptoPro.Sharpei..::..Gost2012_256KeyExchangeFormatter

Потокобезопасность

Любые открытые члены этого типа, объявленные как static (Shared в Visual Basic), являются потокобезопасными. Потокобезопасность членов экземпляров не гарантирована.

См. также: