КриптоПро.NET SDK working with EDS

How to sign and encrypt a file using the library КриптоПро.NET SDK with a USB token? Alg. signature GOST 34.10-2001 (512 bits) Alg. hash GOST 34-11-94

I have a file in the p7s.p7m format. Its contents are separated by the tags

----- BEGIN PKCS7 ENCRYPTED ----- --- END PKCS7 ENCRYPTED ----- 
Author: Damir Gafarov, 2017-06-28

2 answers

Example of a signature for the GOST 34-10 Algorithm. Source

namespace Samples.MySamples

class Gost3410CSPSample
{
    [STAThread]
    static void Main(string[] args)
    {
        try
        {
            //Создаем новый Гост-34.10 CSP.
            Gost3410CryptoServiceProvider Gost = new Gost3410CryptoServiceProvider();

            //32-х битное значение хэш для подписи.
            byte[] HashValue = { 59, 4, 248, 102, 77, 97, 142, 201, 
                                210, 12, 224, 93, 25, 41, 100, 197, 
                                213, 134,130, 135, 0, 0, 0, 0,
                                0,0,0,0,0,0,0,0};

            //Подписываем значение хэш.
            byte[] SignedHashValue = GostSignHash(HashValue, Gost, "Gost3411");

            //Проверяем правильность подписи и выводим результат.
            bool b = GostVerifyHash(HashValue, SignedHashValue, Gost, "Gost3411");
            if (b)
            {
                Console.WriteLine("Подпись вычислена верно.");
            }
            else
            {
                Console.WriteLine("Подпись вычислена неверно.");
            }
        }
        catch (ArgumentNullException e)
        {
            Console.WriteLine(e.Message);
        }
    }

    static byte[] GostSignHash(byte[] HashToSign, Gost3410CryptoServiceProvider key, string HashAlg)
    {
        try
        {
            //Создаем форматтер подписи с закрытым ключом из переданного 
            //функции криптопровайдера.
            GostSignatureFormatter Formatter = new GostSignatureFormatter((Gost3410CryptoServiceProvider)key);

            //Устанавливаем хэш-алгоритм.
            Formatter.SetHashAlgorithm(HashAlg);

            //Создаем подпись для HashValue и возвращаем ее.
            return Formatter.CreateSignature(HashToSign);
        }
        catch (CryptographicException e)
        {
            Console.WriteLine(e.Message);
            return null;
        }
    }

    static bool GostVerifyHash(byte[] HashValue, byte[] SignedHashValue, AsymmetricAlgorithm key, string HashAlg)
    {
        try
        {
            //Создаем форматтер подписи с закрытым ключом из переданного 
            //функции криптопровайдера.
            GostSignatureDeformatter Deformatter = new GostSignatureDeformatter(key);

            //Устанавливаем хэш-алгоритм.
            Deformatter.SetHashAlgorithm(HashAlg);

            //Проверяем подпись и возвращаем результат. 
            return Deformatter.VerifySignature(HashValue, SignedHashValue);
        }
        catch (CryptographicException e)
        {
            Console.WriteLine(e.Message);
            return false;
        }
    }
}

You can set the container in this way:

CspParameters cspParameters = new CspParameters(75);
cspParameters.KeyContainerName = "MCPUEpOv";
 2
Author: Dmitry, 2017-07-04 11:17:46

I decided to take the path of least resistance and use CryptoPro's Cryptcp console utility. For the utility to work, you need the CryptoPro CSP cryptoprovider. CryptoPro CSP on one machine costs about 2,000 rubles, and Cryptcp about 700 rubles. Cryptcp and APM CryptoPro are compatible with each other.

Forming commands:

 /// <summary>
/// Формирование команд для утилиты Cyptcp
/// </summary>
public static class Command
{
    /// <summary>
    /// Команда на запуск дешифрования
    /// </summary>
    /// <param name="nameCertificate">Имя сертификата</param>
    /// <param name="pathEncryptedFile">Путь к защифрованному файлу </param>
    /// <param name="pathSave">Путь к дешифрованному файлу</param>
    /// <returns></returns>
    public static string Decript(string nameCertificate, string pathEncryptedFile, string pathSave)
    {
        return "-decr -dn \"" + nameCertificate + "\" " +"\""+ pathEncryptedFile + "\"   \"" + pathSave+"\"";
    }

    /// <summary>
    /// Проверка подписи. Сертификат выбирается из хранилища сертификатов
    /// </summary>
    /// <param name="pathSignFile">Путь к подписанному файлу</param>
    /// <param name="path">Путь к очищенному от подписи файлу</param>
    /// <returns></returns>
    public static string VerificationSignature(string pathSignFile, string pathFile)
    {
        return "-verify -verall "  + "\"" + pathSignFile + "\"   \"" + pathFile + "\"";
    }

    public static string Sign(string nameCertificate, string pathFile, string pathSignedFile)
    {
        return "-sign -dn \"" + nameCertificate + "\"  " + "\"" + pathFile + "\"   \"" + pathSignedFile + "\"";
    }

    public static string Encrypt(string nameRecipientCertificate, string pathSigFile, string pathSave)
    {
        return "-encr -dn \"" + nameRecipientCertificate + "\" " + "\"" + pathSigFile + "\"   \"" + pathSave + "\"";
    }
}

Running the utility to execute the command:

   private void RunCommand(string command, string pathApplication)
    {
        using (Process process = new Process())
        {
            //Имя файла.
            process.StartInfo.FileName = pathApplication;
            //Директория.
            process.StartInfo.WorkingDirectory = Path.GetDirectoryName(pathApplication);
            //Команда. 
            process.StartInfo.Arguments = command;

            //Не показывать окно приложения.
            process.StartInfo.CreateNoWindow = true;
            process.StartInfo.UseShellExecute = false;

            process.StartInfo.RedirectStandardInput = true;

            process.StartInfo.StandardOutputEncoding = Encoding.Default;

            process.Start();

            //Ответ на диалог выбора сертификата
            process.StandardInput.WriteLine("y");
        }
    }
 0
Author: Damir Gafarov, 2017-08-04 04:38:08