Статус: Новичок
Группы: Участники
Зарегистрирован: 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);
}
}
}
}
}
}
|