C# 我正在使用SignedXML对WS-Security Soap请求进行签名,但在匹配SOAPUI签名值时遇到问题

C# 我正在使用SignedXML对WS-Security Soap请求进行签名,但在匹配SOAPUI签名值时遇到问题,c#,wcf,ws-security,C#,Wcf,Ws Security,我正在升级以前实现WS-Security的WCF客户端。该服务以前只需要一个有效的证书和一个UsernameToken。提供者已经更改了他们的要求,现在,除了以前的WS-Security元素之外,现在还需要一个Timestamp元素,并且仅对该元素进行数字签名 事实上,我相信我已经很好地实现了这些增强功能。请求“看起来不错”,包括签名。但该服务不接受该请求。它没有说明原因。但我已经确定这是签名 我可以使用SOAP-UI成功发送请求。由于我只对timestamp元素进行签名,因此我认为我应该能够提

我正在升级以前实现WS-Security的WCF客户端。该服务以前只需要一个有效的证书和一个UsernameToken。提供者已经更改了他们的要求,现在,除了以前的WS-Security元素之外,现在还需要一个Timestamp元素,并且仅对该元素进行数字签名

事实上,我相信我已经很好地实现了这些增强功能。请求“看起来不错”,包括签名。但该服务不接受该请求。它没有说明原因。但我已经确定这是签名

我可以使用SOAP-UI成功发送请求。由于我只对timestamp元素进行签名,因此我认为我应该能够提供(出于测试目的)与SOAP-UI请求中使用的wsu:Id、wsu:Created和wsu:Expires相同的值(知道这些值是过时的)并且能够生成与生成的SOAP-UI相同的签名值和引用摘要值

这是一个有效的假设吗

对这种假设的一个挑战是,如果我将整个SOAP信封导入SignedXML对象,那么两个哈希值的值将不同于仅导入wsse:Security元素时的值。这让我感到惊讶,因为每种情况下的签名过程都正确地标识了wsu:Timestamp元素

通过正确识别wsu:Timestamp,我的意思是GetElementId()方法的重载在调用时查找wsu:Timestamp

如果这些基本问题表明我在正确的轨道上,我将包括我已经实现的实际代码:

我已经重写了GetIdeElement以确保识别wsu:Id

我使用framework4.7.1和GetRSAPrivateKey()(从允许私钥导出的证书导入)获取签名密钥

我已经创建了对wsu:Timestamp元素的引用:

<Reference URI="#TS-62B6909D4542C911A415716590862947">
    <Transforms>
      <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
         <InclusiveNamespaces PrefixList="wsse wsu cmaw s soapenv xsd"
                xmlns="http://www.w3.org/2001/10/xml-exc-c14n#" />
      </Transform>
    </Transforms>
    <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
            <DigestValue>TtV9lso1WsMvwhiiKPADpYshmJcb95NZOj6BkuV5UmI=</DigestValue>
</Reference>
我在引用URL的开始处有“#”,在实际引用处没有“#”

无论如何,我的第一个问题是,我是否应该期望能够在受控测试中匹配工作的SOAP-UP签名(过时的值),以及导入整个SOAP信封是否应该生成与仅导入wsse:Security元素不同的签名(我使用一个消息检查器来生成wsse:Security元素,如果没有找到其他方法,我将无法访问整个信封以提供给SignedXML

注意:我在这里和其他地方看过很多好文章,它们解释了如何对消息进行签名。但我目前面临的挑战是获得一个有效的签名——我希望这仅仅意味着匹配SOAP-UI


对此有何想法?

我最终确定SignedXml处理整个SOAP信封时计算的签名值与SignedXml仅处理子集时计算的签名值不同。我不理解为什么会出现这种情况,因为我只对存在的Timestamp元素进行签名在这两种情况下,都是通过SignedXml正确定位的,但我没有必要知道这个特殊的“原因”


在重构之后,客户端现在可以基于整个soap信封进行签名。

我最终确定SignedXml处理整个soap信封时计算的签名值与SignedXml仅处理子集时计算的签名值不同。我不明白为什么这是case,因为我只对Timestamp元素进行了签名,它在两种情况下都存在,并且由SignedXml正确定位

在重构之后,客户机现在可以基于整个soap信封进行签名

CryptoConfig.AddAlgorithm(typeof   (RSAPKCS1SHA256SignatureDescription), "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256");

signedXML.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl;