WCF 客户端 - 指定 WS-Security Timestamp 签名的签名算法

发布于 2025-01-07 13:53:58 字数 5841 浏览 0 评论 0 原文

我有一个 WCF 客户端正在向非 WCF 服务发送消息,并且该服务在处理用于对 WS-Security Timestamp 元素进行签名的 HMAC-SHA1 签名方法时遇到问题。理想情况下,我们希望使用 RSA-SHA1 签名方法,但我无法让 WCF 使用该签名方法。

我使用的绑定是自定义绑定,它允许我通过 HTTPS 发送 SAML 2.0 令牌:

<customBinding>
    <!-- This binding is a WS2007FederationHttpBinding without Secure Sessions that uses Text message encoding. -->
    <binding
        name="WS2007FederationHttpBinding_NoSecureSession_Text"
        closeTimeout="00:01:00"
        openTimeout="00:01:00"
        receiveTimeout="00:10:00"
        sendTimeout="00:01:00">
        <security
            authenticationMode="IssuedTokenOverTransport"
            requireSignatureConfirmation="true"
            securityHeaderLayout="Lax"
            messageSecurityVersion="WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10"
            keyEntropyMode="CombinedEntropy"
            includeTimestamp="true">
            <issuedTokenParameters
                tokenType="urn:oasis:names:tc:SAML:2.0:assertion">
                <!-- This describes the STS. That is, the URL, the binding to use, and its Identity -->
                <issuer
                    address="http://hostname//STS.svc"
                    binding="ws2007HttpBinding"
                    bindingConfiguration="StsUserNameBindingConfiguration">
                    <identity>
                        <!-- This is the certificate used for signing on the STS. -->
                        <!-- Replace "sts-signing-certificate-thumbprint" with the actual thumbprint of the STS's signing certificate -->
                        <certificateReference
                            findValue="sts-signing-certificate-thumbprint"
                            storeLocation="LocalMachine"
                                storeName="My"
                                x509FindType="FindByThumbprint"/>
                    </identity>
                </issuer>
            </issuedTokenParameters>

            <!-- This basically says "Don't use Secure Conversation" -->
            <secureConversationBootstrap/>
        </security>

        <!-- Use Text Encoding -->
        <textMessageEncoding/>

        <!-- This says to use HTTPS when communicating with the remote service -->
        <httpsTransport
            requireClientCertificate="true"
            maxBufferPoolSize="134217728"
            maxReceivedMessageSize="134217728"
            maxBufferSize="134217728"/>
    </binding>
</customBinding>

传出请求中的签名如下所示:

<Signature
    xmlns="http://www.w3.org/2000/09/xmldsig#">
    <SignedInfo>
        <CanonicalizationMethod
            Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
        <SignatureMethod
            Algorithm="http://www.w3.org/2000/09/xmldsig#hmac-sha1"/>
        <Reference
            URI="#_0">
            <Transforms>
                <Transform
                    Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
            </Transforms>
            <DigestMethod
                Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
            <DigestValue>GZfW1RkyS4DHYFPHRnRuqNSo+qE=</DigestValue>
        </Reference>
    </SignedInfo>
    <SignatureValue>rMzQ/kEV7AXcO3wm9hfQXNoX5r4=</SignatureValue>
    <KeyInfo>
        <o:SecurityTokenReference
            b:TokenType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0"
            xmlns:b="http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd">
            <o:KeyIdentifier
                ValueType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLID">_9f79359e-63dc-4e38-888c-6567dac4b41b</o:KeyIdentifier>
        </o:SecurityTokenReference>
    </KeyInfo>
</Signature>

注意 http://www.w3.org/2000/09/xmldsig#hmac-sha1

一件有趣的事情是,HMAC-SHA1 算法是对称的(需要一把密钥来加密和解密),而 RSA-SHA1 是非对称的(需要一把密钥来加密,一把密钥来解密)。我认为 WCF 使用 HMAC-SHA1 算法,因为它是对称的,并且交换的 SAML 令牌是共享秘密(密钥)。使用 SAML 令牌作为对称算法的共享密钥是有意义的,但是否有一个选项可以强制 WCF 使用 RSA-SHA1 等非对称算法?

我已经能够通过更改 binding/security/defaultAlgorithmSuite 属性对签名方法进行一些细微的修改,但各种选项无法让我在此处指定 RSA-SHA1:

defaultAlgorithm = Default:

defaultAlgorithm = Basic256:

defaultAlgorithm = Basic256Rsa15:

defaultAlgorithm = Basic256Sha256:

defaultAlgorithm = Basic256Sha256Rsa15:

有没有办法强制 WCF 在时间戳上使用 RSA-SHA1签名?

I have a WCF client that is sending a message to a non-WCF service and that service is having problems handling the HMAC-SHA1 signature method used to sign the WS-Security Timestamp element. Ideally, we'd like to use the RSA-SHA1 signature method but I have not been able to get WCF to use that signature method.

The binding I am using is a custom binding which is allowing me to send a SAML 2.0 token over HTTPS:

<customBinding>
    <!-- This binding is a WS2007FederationHttpBinding without Secure Sessions that uses Text message encoding. -->
    <binding
        name="WS2007FederationHttpBinding_NoSecureSession_Text"
        closeTimeout="00:01:00"
        openTimeout="00:01:00"
        receiveTimeout="00:10:00"
        sendTimeout="00:01:00">
        <security
            authenticationMode="IssuedTokenOverTransport"
            requireSignatureConfirmation="true"
            securityHeaderLayout="Lax"
            messageSecurityVersion="WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10"
            keyEntropyMode="CombinedEntropy"
            includeTimestamp="true">
            <issuedTokenParameters
                tokenType="urn:oasis:names:tc:SAML:2.0:assertion">
                <!-- This describes the STS. That is, the URL, the binding to use, and its Identity -->
                <issuer
                    address="http://hostname//STS.svc"
                    binding="ws2007HttpBinding"
                    bindingConfiguration="StsUserNameBindingConfiguration">
                    <identity>
                        <!-- This is the certificate used for signing on the STS. -->
                        <!-- Replace "sts-signing-certificate-thumbprint" with the actual thumbprint of the STS's signing certificate -->
                        <certificateReference
                            findValue="sts-signing-certificate-thumbprint"
                            storeLocation="LocalMachine"
                                storeName="My"
                                x509FindType="FindByThumbprint"/>
                    </identity>
                </issuer>
            </issuedTokenParameters>

            <!-- This basically says "Don't use Secure Conversation" -->
            <secureConversationBootstrap/>
        </security>

        <!-- Use Text Encoding -->
        <textMessageEncoding/>

        <!-- This says to use HTTPS when communicating with the remote service -->
        <httpsTransport
            requireClientCertificate="true"
            maxBufferPoolSize="134217728"
            maxReceivedMessageSize="134217728"
            maxBufferSize="134217728"/>
    </binding>
</customBinding>

The signature in the outgoing request looks like this:

<Signature
    xmlns="http://www.w3.org/2000/09/xmldsig#">
    <SignedInfo>
        <CanonicalizationMethod
            Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
        <SignatureMethod
            Algorithm="http://www.w3.org/2000/09/xmldsig#hmac-sha1"/>
        <Reference
            URI="#_0">
            <Transforms>
                <Transform
                    Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
            </Transforms>
            <DigestMethod
                Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
            <DigestValue>GZfW1RkyS4DHYFPHRnRuqNSo+qE=</DigestValue>
        </Reference>
    </SignedInfo>
    <SignatureValue>rMzQ/kEV7AXcO3wm9hfQXNoX5r4=</SignatureValue>
    <KeyInfo>
        <o:SecurityTokenReference
            b:TokenType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0"
            xmlns:b="http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd">
            <o:KeyIdentifier
                ValueType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLID">_9f79359e-63dc-4e38-888c-6567dac4b41b</o:KeyIdentifier>
        </o:SecurityTokenReference>
    </KeyInfo>
</Signature>

Notice the <SignatureMethod> is http://www.w3.org/2000/09/xmldsig#hmac-sha1

One interesting thing is that the HMAC-SHA1 algorithm is symmetric (one key to encrypt and decrypt) while RSA-SHA1 is asymmetric (requires one key to encrypt and one to decrypt). I think WCF uses the HMAC-SHA1 algorithm because it is symmetric and the SAML token being exchanged is the shared secret (key). It makes sense to use the SAML token as the shared key for a symmetric algorithm but is there an option available to force WCF to use an asymmetric algorithm like RSA-SHA1?

I have been able to get some slight modification of the signature method by changing the binding/security/defaultAlgorithmSuite attribute but the various options do not give me the ability to specify RSA-SHA1 here:

defaultAlgorithm = Default:

<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#hmac-sha1"/>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>

defaultAlgorithm = Basic256:

<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#hmac-sha1"/>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>

defaultAlgorithm = Basic256Rsa15:

<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#hmac-sha1"/>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>

defaultAlgorithm = Basic256Sha256:

<SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#hmac-sha256"/>
<DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>

defaultAlgorithm = Basic256Sha256Rsa15:

<SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#hmac-sha256"/>
<DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>

Is there a way I can force WCF to use RSA-SHA1 on the Timestamp signature?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

回忆凄美了谁 2025-01-14 13:53:58

我认为这是一个互操作性问题。下面的链接中也有类似的问题。

http://www.fokkog.com/2011/01/ ws-security-interoperability-issue.html

您可以手动创建并签署令牌。查看这篇文章:

如何使 WCF 客户端符合特定的 WS-Security - 签署 UsernameToken 和 SecurityTokenReference

I think it is an interoperability issue. There is a similar issue in the link bellow.

http://www.fokkog.com/2011/01/ws-security-interoperability-issue.html

You can manually create and sign the token. Check this post:

How to make WCF Client conform to specific WS-Security - sign UsernameToken and SecurityTokenReference

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文