Ключевое слово в защите информации
КЛЮЧЕВОЕ СЛОВО
в защите информации
Получить ГОСТ TLS-сертификат для домена (SSL-сертификат)
Добро пожаловать, Гость! Чтобы использовать все возможности Вход или Регистрация.

Уведомление

Icon
Error

Опции
К последнему сообщению К первому непрочитанному
Offline RAFA-1995  
#1 Оставлено : 29 октября 2020 г. 13:00:31(UTC)
RAFA-1995

Статус: Новичок

Группы: Участники
Зарегистрирован: 29.10.2020(UTC)
Сообщений: 1
Российская Федерация
Откуда: Краснодар

Всем привет.
Возникла такая проблема пишу на C# приложение по подписанию документов ворд ЭЦП
Ниже приведен код, который подписывает документ.
но после подписания, подпись в документе является недействительной.

Для теста я выпустил себе сертификат ключом RSA и выбрал алгоритм шифрования CPSignedXml.XmlDsigGost3411Url; Документ подписывается корректно

Если я использую сертификат открытым ключом Гост Р 34.10.-2012 256 бит (512) и выбираю алгоритм шифрования CPSignedXml.XmlDsigGost3411_2012_256Url;
то документ подписывается с ошибкой (недействительный сертификат)

Если я использую сертификат открытым ключом Гост Р 34.10.-2012 256 бит (512) и выбираю алгоритм шифрования CPSignedXml.XmlDsigGost3411_2012_512Url;
то программа падает в ошибку и сообщает о том что такой алгоритм не поддерживается
Форумчане подскажите что делать??

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

// Пример подписи документа Office.

using System;
using System.Security.Cryptography.X509Certificates;
using System.IO.Packaging;
using System.Collections.Generic;
using System.Security.Cryptography;
using CryptoPro.Sharpei.Xml;
using System.Security.Cryptography.Xml;
using System.Xml;

namespace Simple35.Office
{
    /// <summary>
    /// По мотивам http://blogs.msdn.com/b/vsod/archive/2009/06/19/how-to-sign-the-signatureline-using-office-open-xml.aspx
    /// </summary>
    public class Sign
    {
        static readonly string RT_OfficeDocument = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument";
        static readonly string OfficeObjectID = "idOfficeObject";
        static readonly string SignatureID = "idPackageSignature";
        //static readonly string SignatureID = "idPackageSignature";
        static readonly string ManifestHashAlgorithm = CPSignedXml.XmlDsigGost3411_2012_256Url;

        [STAThread]
        public static int Main(string[] args)
        {
            // Разбираем аргументы
            if (args.Length < 2)
            {
                Console.WriteLine("Office.Sign <document> <certificate-dn>");
                return 1;
            }
            string document = args[0];
            //string certificate_dn = args[1];

            // Находим секретный ключ по сертификату в хранилище MY
            X509Store store = new X509Store("My", StoreLocation.CurrentUser);
            store.Open(OpenFlags.OpenExistingOnly | OpenFlags.ReadOnly);
            
            //X509Certificate2Collection found = store.Certificates.Find(
            //    X509FindType.FindBySubjectName, certificate_dn, true);

            //if (found.Count == 0)
            //{
            //    Console.WriteLine("Секретный ключ не найден.");
            //    return 1;
            //}
            //if (found.Count > 1)
            //{
            //    Console.WriteLine("Найдено более одного секретного ключа.");
            //    return 1;
            //}
            var fdd = store.Certificates[3];
            X509Certificate2 certificate = fdd;

            using (Package package = Package.Open(document))
            {
                //SignAllParts(package, certificate);
                SignAllParts(package, certificate);
            }

            Console.WriteLine("Документ {0} успешно подписан на ключе {1}.",
                document, certificate.Subject);
            store.Close();
            return 0;
        }


        private static void SignAllParts(Package package)
        {
            if (package == null)
                throw new ArgumentNullException("SignAllParts(package)");

            // Create the DigitalSignature Manager
            PackageDigitalSignatureManager dsm =
                new PackageDigitalSignatureManager(package);
            
            { }
            dsm.CertificateOption =
                CertificateEmbeddingOption.InSignaturePart;

            // Create a list of all the part URIs in the package to sign
            // (GetParts() also includes PackageRelationship parts).                
            System.Collections.Generic.List<Uri> toSign =
                new System.Collections.Generic.List<Uri>();
            foreach (PackagePart packagePart in package.GetParts())
            {
                // Add all package parts to the list for signing.
                toSign.Add(packagePart.Uri);
            }

            // Add the URI for SignatureOrigin PackageRelationship part.
            // The SignatureOrigin relationship is created when Sign() is called.
            // Signing the SignatureOrigin relationship disables counter-signatures.
            toSign.Add(PackUriHelper.GetRelationshipPartUri(dsm.SignatureOrigin));

            // Also sign the SignatureOrigin part.
            toSign.Add(dsm.SignatureOrigin);

            // Add the package relationship to the signature origin to be signed.
            toSign.Add(PackUriHelper.GetRelationshipPartUri(new Uri("/", UriKind.RelativeOrAbsolute)));

            // Sign() will prompt the user to select a Certificate to sign with.
            try
            {
                dsm.Sign(toSign);
            }

            // If there are no certificates or the SmartCard manager is
            // not running, catch the exception and show an error message.
            catch (CryptographicException ex)
            {
                Console.WriteLine(
                    "Cannot Sign\n" + ex.Message,
                    "No Digital Certificates Available"
                    );
            }
        }// e

        private static void SignAllParts(Package package, X509Certificate certificate)
        {
            List<Uri> PartstobeSigned = new List<Uri>();
            List<PackageRelationshipSelector> SignableReleationships = new List<PackageRelationshipSelector>();

            foreach (PackageRelationship relationship in package.GetRelationshipsByType(RT_OfficeDocument))
            {
                // Pass the releationship of the root. This is decided based on the RT_OfficeDocument 
                // http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument
                CreateListOfSignableItems(relationship, PartstobeSigned, SignableReleationships);
            }
            // Create the DigitalSignature Manager
            PackageDigitalSignatureManager dsm = new PackageDigitalSignatureManager(package);
            dsm.CertificateOption = CertificateEmbeddingOption.InSignaturePart;
            //dsm. "urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34102012-gostr34112012-256";
            dsm.HashAlgorithm = ManifestHashAlgorithm;
            try
            {
                System.Security.Cryptography.Xml.DataObject officeObject = CreateOfficeObject(SignatureID, dsm.HashAlgorithm);
                Reference officeObjectReference = new Reference("#" + OfficeObjectID);
                var sgn = dsm.Sign(PartstobeSigned, certificate, SignableReleationships, SignatureID, new System.Security.Cryptography.Xml.DataObject[] { officeObject }, new Reference[] { officeObjectReference });
                //var sgn = dsm.Sign(PartstobeSigned, certificate, SignableReleationships, SignatureID, new System.Security.Cryptography.Xml.DataObject[] { officeObject });
            }
            catch (CryptographicException ex)
            {
                Console.WriteLine(ex.InnerException.ToString());
            }

        }
        static System.Security.Cryptography.Xml.DataObject CreateOfficeObject(
           string signatureID, string manifestHashAlgorithm)
        {
            XmlDocument document = new XmlDocument();
            document.LoadXml(String.Format(
            "<OfficeObject>" +
                "<SignatureProperties xmlns=\"http://www.w3.org/2000/09/xmldsig#\">" +
                    "<SignatureProperty Id=\"idOfficeV1Details\" Target=\"{0}\">" + 
                        "<SignatureInfoV1 xmlns=\"http://schemas.microsoft.com/office/2006/digsig\">" +
                          "<SetupID></SetupID>" +
                          "<ManifestHashAlgorithm>{1}</ManifestHashAlgorithm>" +
                          "<SignatureProviderId>{2}</SignatureProviderId>" + 
                        "</SignatureInfoV1>" +
                    "</SignatureProperty>" + 
                "</SignatureProperties>" +
            "</OfficeObject>", signatureID, manifestHashAlgorithm, "{649A9A268471501FF7852287F789C6B545956CB5}"));
            System.Security.Cryptography.Xml.DataObject officeObject = new System.Security.Cryptography.Xml.DataObject();
            // do not change the order of the following two lines
            officeObject.LoadXml(document.DocumentElement); // resets ID
            officeObject.Id = OfficeObjectID; // required ID, do not change
            return officeObject;
        }

        static void CreateListOfSignableItems(PackageRelationship relationship, List<Uri> PartstobeSigned, List<PackageRelationshipSelector> SignableReleationships)
        {
            // This function adds the releation to SignableReleationships. And then it gets the part based on the releationship. Parts URI gets added to the PartstobeSigned list.
            PackageRelationshipSelector selector = new PackageRelationshipSelector(relationship.SourceUri, PackageRelationshipSelectorType.Id, relationship.Id);
            SignableReleationships.Add(selector);
            if (relationship.TargetMode == TargetMode.Internal)
            {
                PackagePart part = relationship.Package.GetPart(PackUriHelper.ResolvePartUri(relationship.SourceUri, relationship.TargetUri));
                if (PartstobeSigned.Contains(part.Uri) == false)
                {
                    PartstobeSigned.Add(part.Uri);
                    // GetRelationships Function: Returns a Collection Of all the releationships that are owned by the part.
                    foreach (PackageRelationship childRelationship in part.GetRelationships())
                    {
                        CreateListOfSignableItems(childRelationship, PartstobeSigned, SignableReleationships);
                    }
                }
            }
        }
    }
}
RSS Лента  Atom Лента
Пользователи, просматривающие эту тему
Быстрый переход  
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.