我正在构建需要wse安全性的soap消息,并且出于某种原因,客户端需要KeyInfo,subject和serial#。但x509的序列号显示为十六进制,不符合X509SerialNumber节点的xsd要求,即整数。我已经读过这需要发行者序列号#但它不是证书的一部分。这是一个自签名证书。如何确定序列号是什么?
请不要告诉我使用WCF。如果我可以使用它,我会的。我知道WCF会让它更容易,我为WCF持有一个MCTS。
答案 0 :(得分:2)
证书只有一个序列号字段,它是二进制数据。发行人可以在那里放任何东西。实际上,序列号被视为一个非常大的整数,但如果您只检查保存该数字的字节数组,则此类数字看起来像二进制数。因此,您需要将此值视为一个巨大的数字,并将其转换为“可读”的形式。例如。如果你有4字节长的字节数组包含FF 00 FF 00(4字节),字符串表示将是“4278255360”
更新:我的上述解释适用于XMLDSig和XMLEnc标准。在其他标准中(或仅用于显示目的),可以使用其他格式(例如base64,base16编码等)。
答案 1 :(得分:1)
只需要添加一些代码。 X509ChainElement.Certificate.GetSerialNumberString()给了我我需要的东西,我不需要计算任何东西。
以下是我正在使用的代码
public static XmlElement GenerateSignature(XmlElement xmlToSign, StoreName storeName, StoreLocation storeLocation, X509Certificate2 certificate, string referenceID)
{
SignedXml signedXml = new SignedXml(xmlToSign);
signedXml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl;
signedXml.SigningKey = certificate.PrivateKey;
Reference tRef = new Reference(referenceID);
XmlDsigExcC14NTransform env = new XmlDsigExcC14NTransform();
tRef.AddTransform(env);
signedXml.AddReference(tRef);
KeyInfo keyInfo = new KeyInfo();
X509Chain x509Chain = new X509Chain();
x509Chain.Build(certificate);
foreach (X509ChainElement element in x509Chain.ChainElements)
{
KeyInfoX509Data x509Data = new KeyInfoX509Data(element.Certificate);
string issuer = element.Certificate.Issuer;
x509Data.AddIssuerSerial(issuer, element.Certificate.GetSerialNumberString());
keyInfo.AddClause(x509Data);
}
signedXml.KeyInfo = keyInfo;
signedXml.ComputeSignature();
XmlElement xmlDsig = signedXml.GetXml();
return xmlDsig;
}