Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 数字签名显示错误的签名日期_C#_Digital Signature - Fatal编程技术网

C# 数字签名显示错误的签名日期

C# 数字签名显示错误的签名日期,c#,digital-signature,C#,Digital Signature,我正在学习数字签名以及如何在c#中签名。以下是我的代码: Signature.cs public class Signature { static readonly string RT_OfficeDocument = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument"; static readonly string OfficeObjectID

我正在学习数字签名以及如何在c#中签名。以下是我的代码:

Signature.cs

    public class Signature
    {
    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 ManifestHashAlgorithm = "http://www.w3.org/2000/09/xmldsig#sha1";

    // Entry Point
    public static void DigiSign(string tempfile)
    {
    // Open the Package    
        using (Package package = Package.Open(tempfile))
        {
            // Get the certificate
            X509Certificate2 certificate = GetCertificate();
            SignAllParts(package, certificate);
        }
    }

    private static void SignAllParts(Package package, X509Certificate certificate)
    {
        if (package == null) throw new ArgumentNullException("SignAllParts(package)");
        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;

        string signatureID = SignatureID;
        string manifestHashAlgorithm = ManifestHashAlgorithm;
        System.Security.Cryptography.Xml.DataObject officeObject = CreateOfficeObject(signatureID, manifestHashAlgorithm);
        Reference officeObjectReference = new Reference("#" + OfficeObjectID);

        try
        {
            dsm.Sign(PartstobeSigned, certificate, SignableReleationships, signatureID, new System.Security.Cryptography.Xml.DataObject[] { officeObject }, new Reference[] { officeObjectReference });
        }
        catch (CryptographicException ex)
        {
            Console.WriteLine(ex.InnerException.ToString());
        }

    }// end:SignAllParts()

    /**************************SignDocument******************************/
    //  This function is a helper function. The main role of this function is to 
    //  create two lists, one with Package Parts that you want to sign, the other 
    //  containing PacakgeRelationshipSelector objects which indicate relationships to sign.
    /*******************************************************************/
    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);
                }
            }
        }
    }
    /**************************SignDocument******************************/
    //  Once you create the list and try to sign it, Office will not validate the Signature.
    //  To allow Office to validate the signature, it requires a custom object which should be added to the 
    //  signature parts. This function loads the OfficeObject.xml resource.
    //  Please note that GUID being passed in document.Loadxml. 
    //  Background Information: Once you add a SignatureLine in Word, Word gives a unique GUID to it. Now while loading the
    //  OfficeObject.xml, we need to make sure that The this GUID should match to the ID of the signature line. 
    //  So if you are generating a SignatureLine programmtically, then mmake sure that you generate the GUID for the 
    //  SignatureLine and for this element. 
    /*******************************************************************/

    static System.Security.Cryptography.Xml.DataObject CreateOfficeObject(
       string signatureID, string manifestHashAlgorithm)
    {
        XmlDocument document = new XmlDocument();
        document.LoadXml(String.Format(Properties.Resources.OfficeObject, signatureID, manifestHashAlgorithm, "{3CF6B91E-C5F6-46A4-B036-72597274FCC0}"));
        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 X509Certificate2 GetCertificate()
    {
        X509Store certStore = new X509Store(StoreLocation.CurrentUser);
        certStore.Open(OpenFlags.ReadOnly);
        X509Certificate2Collection certs = X509Certificate2UI.SelectFromCollection(certStore.Certificates, "Select a certificate", "Please select a certificate",
                X509SelectionFlag.SingleSelection);
        return certs.Count > 0 ? certs[0] : null;
    }
}
以及签名后的abc.docx文件:

在签名的附加信息中,系统日期/时间(签名时间)与我的本地时间和日期/时间格式不同。我尝试更改本地时区并重置日期/时间,但仍然不起作用。
我缺少什么?

使用.NET安全黑盒解决我的问题

对话框中显示的时间可能是您的UTC时间?我的时区是GMT+7。正如您在我的图片(上面的链接)中所看到的,签名时间与任务栏中我的本地时间不匹配。
如您在我的图片(上面的链接)中所看到的,
请在问题文本中提供该信息。很多人(比如我)不会点击外部链接。你什么时候签的?上面说你什么时候签的?您居住在哪个时区?@mjwills我在下午1:40签署了它,我的时区是UTC+07:00。运行上述代码后,我打开文档并查看我在其中签署的签名。在对话框中显示:以下附加信息存储在签名中:系统日期/时间:8:40 PM,这是错误的。1:40 PM+7小时=8:40 PM
class Program
{
    static void Main(string[] args)
    {
            Signature.DigiSign(@"D:\abc.docx");
    }
}