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

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

Синтаксис

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

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

Заметки

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

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

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

Примеры

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

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

Imports System
Imports System.IO
Imports System.Security.Cryptography
Imports CryptoPro.Sharpei


Class KeyExchange

    Shared Sub Main()

        Try

            ' Создаем объект шифрования со сгенерированным ключом и синхропосылкой.

            Dim gost As Gost28147 = Gost28147.Create()

            ' Строка для шифрования.
            Dim Data As String = "Here is some data to encrypt."
            Dim FileName As String = "Test.txt"

            ' Шифруем текст и сохраняем в файле.
            EncryptTextToFile(Data, FileName, gost)

            'Расшифровываем текст файла.
            Dim result As String = DecryptTextFromFile(FileName, gost)

            Console.WriteLine(result)
            Console.ReadLine()

        Catch e As Exception
            Console.WriteLine(e.Message)

        End Try
    End Sub

    Shared Sub EncryptTextToFile(ByVal Data As String, _
            ByVal FileName As String, ByVal gost As Gost28147)
        Try

            ' Открываем или создаем файл.
            Dim fStream As FileStream = File.Open(FileName, FileMode.OpenOrCreate)

            ' Создаем CryptoStream, используя FileStream, 
            ' переданный ключ и синхропосылку (IV).
            Dim cStream As CryptoStream = New CryptoStream(fStream, _
                gost.CreateEncryptor(), CryptoStreamMode.Write)

            ' Создаем StreamWriter, используя CryptoStream.
            Dim sWriter As StreamWriter = New StreamWriter(cStream)

            ' Пишем данные в поток, зашифровая их.
            sWriter.WriteLine(Data)

            ' Закрываем все потоки.
            sWriter.Close()
            cStream.Close()
            fStream.Close()

        Catch e As CryptographicException
            Console.WriteLine("A Cryptographic error occurred: {0}", e.Message)

        Catch e As UnauthorizedAccessException
            Console.WriteLine("A file error occurred: {0}", e.Message)

        End Try
    End Sub

    Shared Function DecryptTextFromFile(ByVal FileName As String, _
            ByVal gost As Gost28147) As String

        Try
            ' Открываем файл. 
            Dim fStream As FileStream = File.Open(FileName, FileMode.Open)

            ' Создаем CryptoStream, используя FileStream, 
            ' переданный ключ и синхропосылку (IV).
            Dim cStream As CryptoStream = New CryptoStream(fStream, _
                gost.CreateDecryptor(), CryptoStreamMode.Read)

            ' Создаем StreamWriter, используя CryptoStream.
            Dim sReader As StreamReader = New StreamReader(cStream)

            ' Считываем данные из потока, расшифровывая их. 
            Dim val As String = sReader.ReadLine()

            ' Закрываем все потоки.
            sReader.Close()
            cStream.Close()
            fStream.Close()

            Return val

        Catch e As CryptographicException
            Console.WriteLine("A Cryptographic error occurred: {0}", e.Message)
            Return Nothing

        Catch e As UnauthorizedAccessException
            Console.WriteLine("A file error occurred: {0}", e.Message)
            Return Nothing
        End Try
    End Function

End Class
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 KeyExchange
    {
        // Ассиметричный ключ получателя.
        private Gost3410 AssymKey;
        // Синхропосылка.
        private byte[] IV;

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

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

            // Создаем форматтер, шифрующий на ассиметричном ключе получателя.
            GostKeyExchangeFormatter Formatter = new GostKeyExchangeFormatter(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 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)
        {
            // Деформаттер для ключей, зашифрованных на ассиметричном ключе получателя.
            GostKeyExchangeDeformatter Deformatter = new GostKeyExchangeDeformatter(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..::..GostKeyExchangeFormatter

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

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

См. также: