c# - c# 签署 XML 文档:x509 证书中有什么
问题描述
我正在将软件许可系统整合到我的程序中。客户端请求许可证,向我发送我需要的数据,然后我生成一个 XML 文件,这是我的程序必须在客户端检查的许可证文件。
所以我在我的开发计算机(win10)上生成了一个 x509 证书并签署了许可证文件。
X509Store store = new X509Store(StoreName, StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly);
X509Certificate2Collection certCollection = store.Certificates;
X509Certificate2Collection currentCerts = certCollection.Find(X509FindType.FindByTimeValid, DateTime.Now, false);
X509Certificate2Collection signingCert = currentCerts.Find(X509FindType.FindBySubjectDistinguishedName, $"CN={CertificateName}", false);
X509Certificate2 cert = signingCert[0]; // has private and public
store.Close();
CryptoConfig.AddAlgorithm(typeof(RSAPKCS1SHA256SignatureDescription), "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256");
var exportedKeyMaterial = signingCert[0].PrivateKey.ToXmlString(true);
var key = new RSACryptoServiceProvider(new CspParameters(24));
key.PersistKeyInCsp = true;
key.FromXmlString(exportedKeyMaterial);
XmlDocument doc = new XmlDocument();
doc.PreserveWhitespace = true;
// LicenseInfo is the info about her computer etc. my client provides, eg. by e-mail
using (TextReader sr = new StringReader(LicenseInfo))
{
doc.Load(sr);
}
SignedXml signedXml = new SignedXml(doc);
signedXml.SigningKey = key;
signedXml.SignedInfo.SignatureMethod = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256";
Reference reference = new Reference();
reference.AddTransform(new XmlDsigEnvelopedSignatureTransform());
reference.AddTransform(new XmlDsigExcC14NTransform());
reference.Uri = "";
reference.DigestMethod = "http://www.w3.org/2001/04/xmlenc#sha256";
signedXml.AddReference(reference);
KeyInfo keyInfo = new KeyInfo();
keyInfo.AddClause(new KeyInfoX509Data(cert));
signedXml.KeyInfo = keyInfo;
signedXml.ComputeSignature();
XmlElement sig = signedXml.GetXml();
doc.DocumentElement.AppendChild(doc.ImportNode(sig,true));
if (doc.FirstChild is XmlDeclaration)
{
doc.RemoveChild(doc.FirstChild);
}
// and here it finally is: the license!
LicenseText = doc.OuterXml;
签名进入许可证文件,签名后将如下所示:
<License>
<MailAddress>....</MailAddress>
<LicenseNr>8309847560354</LicenseNr>
<RequestTimeStamp>8/15/2019 11:28:47 AM</RequestTimeStamp>
<ExpirationTimeStamp>8/14/2020 11:28:47 AM</ExpirationTimeStamp>
<X5>78-BB-2F-65-4blabla45-A8-B5-4D-82</X5>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />
<SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" />
<Reference URI="">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
<DigestValue>Gg9WLq12JSYFh6tatRTCnGbzEzMg8PidcXK4iWwPcXg=</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>JdC09BIeHcw8...q24JFVseBZWXOo==</SignatureValue>
<KeyInfo>
<X509Data>
<X509Certificate>MIIC8zCCAd+gAwIBAgIQgwuqv2X..........oP7f5f</X509Certificate>
</X509Data>
</KeyInfo>
</Signature>
</License>
<X509Certificate/> 里面是什么?我的公钥?如果是这样,我不需要将我的公钥作为嵌入资源包含在程序中,因为它将在我的客户许可证文件中,无论如何都必须处理......对吗?不会包括我的私钥,我希望......?
这是我(尝试)验证许可证有效性的方法(不包括到期日期,仅查看许可证文件是否未被篡改)
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.Load(Name); // the license file
SignedXml signedXml = new SignedXml(xmlDocument);
XmlNodeList nodeList = xmlDocument.GetElementsByTagName("Signature");
signedXml.LoadXml((XmlElement)nodeList[0]);
RSACryptoServiceProvider Key = new RSACryptoServiceProvider(new CspParameters(24));
Key.ToXmlString(false);
return signedXml.CheckSignature(Resources.PubKey.FromXmlString()); // ????? or what?
所以:
1:X509Certificate中的签名是什么?
2:验证不起作用。有什么建议么?
3:我是否将我的公钥包含在检查许可证的程序中,还是签名本身就是来源?
PS:
请不要指出这不会给我 100% 的安全性。我知道。我的问题是关于 X509,而不是关于防盗。这是另一个更广泛的问题。这很有趣,对这些东西进行编程和学习。
解决方案
推荐阅读
- java - Android 上的@Module.subcomponents
- angular - 为不同模块中的每个导入添加/加载 SharedModule?
- excel - 带有“#div/0!”的 Excel 公式来计算 Std。偏差
- java - 用两种不同的返回类型在 Java 中实现访问者模式
- python - Sk Learn CountVectorizer:将表情符号保持为单词
- go - 不能在 func 参数中使用 bytes.Buffer 作为类型 io.WriterAt
- python - 有没有更好的方法来编写这个 pyspark 拆分代码?
- mysql - 在 information_schema DB 中区分:默认为 NULL 的列与没有默认值的列
- javascript - 返回响应和访问成员时出现打字稿错误
- javascript - 按下 HTML 按钮时如何显示从 PHP 函数返回的数据