在C#中将签名算法从sha1转换为sha256

问题描述

我有一个Web服务客户端应用程序。我的网络服务提供商通知我,将请求头部分中的签名方法从sha1更改为sha256。目前我有一个CustomSendFilter类,并使用下面的函数来保护传出消息。我如何转换为sha 256?我进行了搜索,但还没有找到确定的解决方案。

public override void SecureMessage(SoapEnvelope envelope,Security security)
        {
            X509SecurityToken signaturetoken;

            signaturetoken = new X509SecurityToken(CertificateManager.ClientCertificate);           
          
            security.Tokens.Add(signaturetoken);
            
            MessageSignature sig = new MessageSignature(signaturetoken);

            security.Elements.Add(sig);
            security.Timestamp.TtlInSeconds = 60;

            Logging.AddToLog(envelope.Envelope.InnerText);
        }

解决方法

您可以设置要通过MessageSignature.SignedInfo.SignatureMethod使用的签名算法。

不幸的是,在撰写本文时,.NET Framework可能尚未内置对http://www.w3.org/2001/04/xmldsig-more#rsa-sha256的支持,但是可以使用以下代码来解决该问题(信用转到https://gist.github.com/sneal/f35de432115b840c4c1f):

/// <summary>
/// SignatureDescription impl for http://www.w3.org/2001/04/xmldsig-more#rsa-sha256
/// </summary>
public class RSAPKCS1SHA256SignatureDescription : SignatureDescription
{
    /// <summary>
    /// Registers the http://www.w3.org/2001/04/xmldsig-more#rsa-sha256 algorithm
    /// with the .NET CrytoConfig registry. This needs to be called once per
    /// appdomain before attempting to validate SHA256 signatures.
    /// </summary>
    public static void Register()
    {
        CryptoConfig.AddAlgorithm(
            typeof(RSAPKCS1SHA256SignatureDescription),"http://www.w3.org/2001/04/xmldsig-more#rsa-sha256");
    }

    /// <summary>
    /// .NET calls this parameterless ctor
    /// </summary>
    public RSAPKCS1SHA256SignatureDescription()
    {
        KeyAlgorithm = "System.Security.Cryptography.RSACryptoServiceProvider";
        DigestAlgorithm = "System.Security.Cryptography.SHA256Managed";
        FormatterAlgorithm = "System.Security.Cryptography.RSAPKCS1SignatureFormatter";
        DeformatterAlgorithm = "System.Security.Cryptography.RSAPKCS1SignatureDeformatter";
    }

    public override AsymmetricSignatureDeformatter CreateDeformatter(AsymmetricAlgorithm key)
    {
        var asymmetricSignatureDeformatter =
            (AsymmetricSignatureDeformatter)CryptoConfig.CreateFromName(DeformatterAlgorithm);
        asymmetricSignatureDeformatter.SetKey(key);
        asymmetricSignatureDeformatter.SetHashAlgorithm("SHA256");
        return asymmetricSignatureDeformatter;
    }

    public override AsymmetricSignatureFormatter CreateFormatter(AsymmetricAlgorithm key)
    {
        var asymmetricSignatureFormatter =
            (AsymmetricSignatureFormatter)CryptoConfig.CreateFromName(FormatterAlgorithm);
        asymmetricSignatureFormatter.SetKey(key);
        asymmetricSignatureFormatter.SetHashAlgorithm("SHA256");
        return asymmetricSignatureFormatter;
    }
}
,

谢谢您的回答。我有一个CustomSendFilter类,用于保护请求,如下所示。我应该在哪里注册算法​​?我在调用webservice函数之前也在下面的SecureMessage函数内部进行了注册,但是没有用。

公共类CustomSendFilter:SendSecurityFilter { 私有字符串serviceDescription;

    public CustomSendFilter(SecurityPolicyAssertion parentAssertion,string serviceDescription)
        : base(parentAssertion.ServiceActor,true)
    {
        this.serviceDescription = serviceDescription;
    }

    public override SoapFilterResult ProcessMessage(SoapEnvelope envelope)
    {
        SoapFilterResult result = base.ProcessMessage(envelope);

        Logging.SaveSoapEnvelope(envelope,SoapMessageDirection.Out,serviceDescription);

        return result;
    }

    public override void SecureMessage(SoapEnvelope envelope,Security security)
    {
        X509SecurityToken signatureToken;


            signatureToken = new X509SecurityToken(CertificateManager.ClientCertificate);
        RSAPKCS1SHA256SignatureDescription.Register();
        security.Tokens.Add(signatureToken);
        
        MessageSignature sig = new MessageSignature(signatureToken);

        security.Elements.Add(sig);
        security.Timestamp.TtlInSeconds = 60;

        Logging.AddToLog(envelope.Envelope.InnerText);
    }

}