I必须在肥皂响应中阀门签名。我用爪哇得到它,但我必须使用.NET做到这一点,但我无法解决。 在这里完成工作的Java代码:
public class SigVal {
private PublicKey publicKey;
public XMLSignatureValidator(PublicKey publicKey) {
this.publicKey = publicKey;
}
public boolean isValid(Node dsSignature)
{
DOMValidateContext context = new DOMValidateContext(publicKey, dsSignature);
String providerName = System.getProperty "jsr105Provider", "org.jcp.xml.dsig.internal.dom.XMLDSigRI");
XMLSignatureFactory factory = XMLSignatureFactory.getInstance("DOM", (Provider) Class
.forName(providerName).newInstance());
XMLSignature signature = factory.unmarshalXMLSignature(context);
boolean coreValidity = signature.validate(context);
}
}
公共密钥来自X509Certificate,从WSSE:二进制核心token产生。 dsSignature节点是DS:签名元素。
肥皂反应:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing">
<SOAP-ENV:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" SOAP-ENV:mustUnderstand="1">
<wsse:BinarySecurityToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" wsu:Id="CertId-33637684">MII..==</wsse:BinarySecurityToken>
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
<ds:Reference URI="#id-23582192">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
<ds:DigestValue>VvfpzVGZkr/AQ3krGcdklXujj3w=</ds:DigestValue>
</ds:Reference>
<ds:Reference URI="#id-961374">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
<ds:DigestValue>KGBEkW1e0fkV3ooAptSIldv9ftQ=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>
StF...=
</ds:SignatureValue>
<ds:KeyInfo Id="KeyId-12282214">
<wsse:SecurityTokenReference xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="STRId-314846">
<wsse:Reference URI="#CertId-33637684" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" />
</wsse:SecurityTokenReference>
</ds:KeyInfo>
</ds:Signature>
<wsu:Timestamp xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="id-23582192">
<wsu:Created>2013-06-06T07:08:19.323Z</wsu:Created>
<wsu:Expires>2013-06-06T07:13:19.323Z</wsu:Expires>
</wsu:Timestamp>
</wsse:Security>
<wsa:MessageID SOAP-ENV:mustUnderstand="0">uuid:dddca070-ce77-11e2-b9ac-d6977a2ed2bf</wsa:MessageID>
<wsa:To SOAP-ENV:mustUnderstand="0">http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To>
<wsa:Action SOAP-ENV:mustUnderstand="0">...</wsa:Action>
<From xmlns="http://schemas.xmlsoap.org/ws/2004/08/addressing" SOAP-ENV:mustUnderstand="0">
<Address>...</Address>
</From>
<wsa:RelatesTo RelationshipType="wsa:Reply" SOAP-ENV:mustUnderstand="0">urn:uuid:3f4f070b-9e28-410d-b10b-a21a7d62ee86</wsa:RelatesTo>
</SOAP-ENV:Header>
<SOAP-ENV:Body xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="id-961374">
...
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
,我尝试了C#
XmlNodeList xmlNodeList = xmlDocument.GetElementsByTagName("wsse:BinarySecurityToken");
string binarySecurityToken = xmlNodeList[0].InnerText;
X509Certificate2 x509Certificate2 = new X509Certificate2(Convert.FromBase64String(binarySecurityToken));
xmlNodeList = xmlDocument.GetElementsByTagName("Signature", "http://www.w3.org/2000/09/xmldsig#");
XmlElement signature = (XmlElement) xmlNodeList[0];
SignedXml signedXml = new SignedXml(xmlDocument);
signedXml.LoadXml(signature);
signedXml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl;
bool isOk = signedXml.CheckSignature();
但是检查签名返回始终为false。我覆盖了signedxml.getIdelement以获取参考元素。但这不做这项工作。
我理解正确:我必须从SOAP消息(DS:签名)中获取签名元素,从SOAP消息中获取证书(WSSE:BinarySecurityToken)并验证它们。
在处理Java Web服务时,这对我有用:
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.PreserveWhitespace = true;
xmlDocument.LoadXml(xmlResponse);
XmlNodeList xmlNodeList = xmlDocument.GetElementsByTagName("wsse:BinarySecurityToken");
string binarySecurityToken = xmlNodeList[0].InnerText;
X509Certificate2 x509Certificate2 = new X509Certificate2(Convert.FromBase64String(binarySecurityToken));
xmlNodeList = xmlDocument.GetElementsByTagName("Signature", "http://www.w3.org/2000/09/xmldsig#");
XmlElement signature = (XmlElement)xmlNodeList[0];
SignedXmlWithId signedXml = new SignedXmlWithId(xmlDocument);
signedXml.LoadXml(signature);
bool isOk = signedXml.CheckSignature(x509Certificate2, true);
首先,您需要在将XML加载到
PreserveWhitespace
对象之前将
true
设置为
XmlDocument
。
如果签名元素的ID具有一个名称空间前缀(如本示例中的
wsu:Id
),则
SignedXml
失败,因此替代方法是子类并覆盖GetIdElement
方法。班级班来自
这个答案。
SignedXmlWithId
lastly,您需要将证书传递给public class SignedXmlWithId : SignedXml
{
public SignedXmlWithId(XmlDocument xml) : base(xml)
{
}
public SignedXmlWithId(XmlElement xmlElement)
: base(xmlElement)
{
}
public override XmlElement GetIdElement(XmlDocument doc, string id)
{
// check to see if it's a standard ID reference
XmlElement idElem = base.GetIdElement(doc, id);
if (idElem == null)
{
XmlNamespaceManager nsManager = new XmlNamespaceManager(doc.NameTable);
nsManager.AddNamespace("wsu", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
idElem = doc.SelectSingleNode("//*[@wsu:Id=\"" + id + "\"]", nsManager) as XmlElement;
}
return idElem;
}
}
方法。,您也不需要设置签名的
CheckSignature
或其他参数 - 所有内容已经写在XML中。
由于.NET 3.5和.NET 4.0之间的规范化实现变化(有关解决方案,请参见HERHI),但我没有这个问题。
此外,请注意在检查签名之前不要对响应XML进行任何格式。 (首先,我使用编辑器将响应保存到XML文件中,并在测试时使用了该XML。这是不起作用的,但是当我直接从Web服务测试响应时,它起作用了。)
)
IDK为什么所有人都使用此XPath
CanonicalizationMethod
我认为更好地使用像这样的东西
doc.SelectSingleNode("//*[@wsu:Id=\"" + id + "\"]", nsManager)