C# 数字签名显示错误的签名日期
我正在学习数字签名以及如何在c#中签名。以下是我的代码: Signature.csC# 数字签名显示错误的签名日期,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
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");
}
}