.NET使用PFX文件签名XML文档
发布时间:2020-12-16 08:28:07 所属栏目:百科 来源:网络整理
导读:一个人如果下决心要成为什么样的人,或者下决心要做成什么样的事,那么,意志或者说动机的驱动力会使他心想事成,如愿以偿。 Program.cs代码: class Program { static void Main( string [] args) { # region 1 - 加载XML文档 var xmlDoc = new XmlDocument(); x
一个人如果下决心要成为什么样的人,或者下决心要做成什么样的事,那么,意志或者说动机的驱动力会使他心想事成,如愿以偿。Program.cs代码:class Program
{
static void Main(string[] args)
{
#region 1 - 加载XML文档
var xmlDoc = new XmlDocument();
xmlDoc.Load(XmlFile);
#endregion
#region 2 - 读取证书文件
var fs = new FileStream(CertificateFile,FileMode.Open);
var certBytes = new byte[fs.Length];
fs.Read(certBytes,0,(Int32)fs.Length);
fs.Close();
var cert = new X509Certificate2(certBytes);
#endregion
#region 3 - 签署xml文档
string signedXmlData = GetSignedXml(xmlDoc,cert);
#endregion
#region 4 - 根据证书验证签名的xml
bool isValid = Validate(signedXmlData,CertificateFile);
System.Console.WriteLine("Signed data validated: {0}",isValid);
#endregion
Console.ReadKey();
}
//公钥加密技术12号标准(Public Key Cryptography Standards #12,PKCS#12)为存储和传输用户或服务器私钥、公钥和证书指定了一个可移植的格式。
public static string CertificateFile { get { return string.Format("{0}{1}{2}",Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location),"Data","certificate.pfx"); } }
public static string XmlFile { get { return string.Format("{0}{1}{2}","sample.xml"); } }
public static string GetSignedXml(XmlDocument xmlDocument,X509Certificate2 certificate)
{
var signedXml = new SignedXml(xmlDocument);
signedXml.SigningKey = certificate.PrivateKey;
//添加签名引用,uri为空,因此整个文档都被签名。
var reference = new Reference();
reference.AddTransform(new XmlDsigEnvelopedSignatureTransform());
reference.AddTransform(new XmlDsigExcC14NTransform());
reference.Uri = "";
signedXml.AddReference(reference);
// 添加证书作为密钥信息,因为这样,具有公钥的证书将被添加到签名部分。
var keyInfo = new KeyInfo();
keyInfo.AddClause(new KeyInfoX509Data(certificate));
signedXml.KeyInfo = keyInfo;
//生成签名
signedXml.ComputeSignature();
//将签名附加在xml文档的末尾
xmlDocument.DocumentElement.AppendChild(signedXml.GetXml());
//获取包含签名节点的XML
return xmlDocument.InnerXml;
}
public static bool Validate(string signedXmlData,string certPath)
{
bool validSender;
try
{
var assertion = new XmlDocument { PreserveWhitespace = true };
assertion.LoadXml(signedXmlData);
// 使用命名空间管理器来避免最糟糕的xpath
var ns = new XmlNamespaceManager(assertion.NameTable);
ns.AddNamespace("ds",SignedXml.XmlDsigNamespaceUrl);
// 获取XML的签名节点
XmlNode signNode = assertion.SelectSingleNode("/ImportantData/ds:Signature",ns);
// 加载XML签名
var signedXml = new SignedXml(assertion.DocumentElement);
signedXml.LoadXml(signNode as XmlElement);
//检查密钥和签名匹配
var cert = new X509Certificate2(certPath);
if (!signedXml.CheckSignature(cert,true))
{
throw new SecurityException("Signature check failed.");
}
else
{
validSender = true;
}
}
catch (Exception ex)
{
throw ex;
}
return validSender;
}
}
Sample.xml<?xml version="1.0" encoding="utf-8" ?>
<ImportantData>
<EmployeeId>13232</EmployeeId>
<Password>ilikeworld</Password>
</ImportantData>
运行结果如图:(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |