c# - 如何在 ASP.NET CORE 中签署 XML SAML 断言

标签 c# asp.net xml

当我尝试签署 XML (SAML) 时,我在 Web Api ASP.NET Core (2.0.2) 中遇到此错误:

System.InvalidOperationException: There is an error in the XML document. ---> System.InvalidOperationException: Instance validation error: 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256' is not a valid value for SignatureMethodAlgorithm.

目标是完整的框架 - .Net 4.7.1。

如果我重新定位到 .Net 4.6.2 和 .Net 4.7,代码可以正常工作。

更新: 事实证明,我使用了第 3 方库,该库期望 SignedXml 中的默认哈希算法为 sha1。作为 .net 4.7.1 的一部分,这已更改为 sha256。这实际上不是签名问题,而是反序列化问题。我根据 .net 4.7.1 文档通过设置上下文切换来修复此问题 https://learn.microsoft.com/en-us/dotnet/framework/migration-guide/retargeting/4.7-4.7.1

最佳答案

我想我过去遇到过这个问题(只是不在核心项目中),我是这样解决的:

将以下类添加到您的项目中:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Web;

namespace xxx.Infrastructure.Crypto
{
    /// <summary>
    ///     <para>
    ///         The RSAPKCS1SHA256SignatureDescription class provides a signature description implementation
    ///         for RSA-SHA256 signatures. It allows XML digital signatures to be produced using the
    ///         http://www.w3.org/2001/04/xmldsig-more#rsa-sha256 signature type.
    ///         RSAPKCS1SHA256SignatureDescription provides the same interface as other signature description
    ///         implementations shipped with the .NET Framework, such as
    ///         <see cref="RSAPKCS1SHA1SignatureDescription" />.
    ///     </para>
    ///     <para>
    ///         RSAPKCS1SHA256SignatureDescription is not generally intended for use on its own, instead it
    ///         should be consumed by higher level cryptography services such as the XML digital signature
    ///         stack. It can be registered in <see cref="CryptoConfig" /> so that these services can create
    ///         instances of this signature description and use RSA-SHA256 signatures.
    ///     </para>
    ///     <para>
    ///         Registration in CryptoConfig requires editing the machine.config file found in the .NET
    ///         Framework installation's configuration directory (such as
    ///         %WINDIR%\Microsoft.NET\Framework\v2.0.50727\Config or
    ///         %WINDIR%\Microsoft.NET\Framework64\v2.0.50727\Config) to include registration information on
    ///         the type. For example:
    ///     </para>
    ///     <example>
    ///         <![CDATA[
    ///             <configuration>
    ///               <mscorlib>
    ///                 <!-- ... -->
    ///                 <cryptographySettings>
    ///                   <cryptoNameMapping>
    ///                     <cryptoClasses>
    ///                       <cryptoClass RSASHA256SignatureDescription="Security.Cryptography.RSAPKCS1SHA256SignatureDescription, Security.Cryptography, Version=1.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
    ///                     </cryptoClasses>
    ///                     <nameEntry name="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" class="RSASHA256SignatureDescription" />
    ///                   </cryptoNameMapping>
    ///                 </cryptographySettings>
    ///               </mscorlib>
    ///             </configuration>
    ///         ]]>
    ///     </example>
    ///     <para>
    ///         After adding this registration entry, the assembly which contains the
    ///         RSAPKCS1SHA256SignatureDescription (in the example above Security.Cryptography.dll) needs to
    ///         be added to the GAC.
    ///    </para>
    ///    <para>
    ///         Note that on 64 bit machines, both the Framework and Framework64 machine.config files should
    ///         be updated, and if the signature description assembly is built bit-specific it needs to be
    ///         added to both the 32 and 64 bit GACs.
    ///     </para>
    ///     <para>
    ///         RSA-SHA256 signatures are first available on the .NET Framework 3.5 SP 1 and as such the
    ///         RSAPKCS1SHA256SignatureDescription requires .NET 3.5 SP 1 and Windows Server 2003 or greater
    ///         to work properly.
    ///     </para>
    ///     <para>
    ///         On Windows 2003, the default OID registrations are not setup for the SHA2 family of hash
    ///         algorithms, and this can cause the .NET Framework v3.5 SP 1 to be unable to create RSA-SHA2
    ///         signatures. To fix this problem, the <see cref="Oid2.RegisterSha2OidInformationForRsa" />
    ///         method can be called to create the necessary OID registrations.
    ///     </para>
    /// </summary>
    public class RSAPKCS1SHA256SignatureDescription : SignatureDescription
    {
        /// <summary>
        ///     Construct an RSAPKCS1SHA256SignatureDescription object. The default settings for this object
        ///     are:
        ///     <list type="bullet">
        ///         <item>Digest algorithm - <see cref="SHA256Managed" /></item>
        ///         <item>Key algorithm - <see cref="RSACryptoServiceProvider" /></item>
        ///         <item>Formatter algorithm - <see cref="RSAPKCS1SignatureFormatter" /></item>
        ///         <item>Deformatter algorithm - <see cref="RSAPKCS1SignatureDeformatter" /></item>
        ///     </list>
        /// </summary>
        public RSAPKCS1SHA256SignatureDescription()
        {
            KeyAlgorithm = typeof(RSACryptoServiceProvider).FullName;
            DigestAlgorithm = typeof(SHA256Managed).FullName;   // Note - SHA256CryptoServiceProvider is not registered with CryptoConfig
            FormatterAlgorithm = typeof(RSAPKCS1SignatureFormatter).FullName;
            DeformatterAlgorithm = typeof(RSAPKCS1SignatureDeformatter).FullName;
        }

        public override AsymmetricSignatureDeformatter CreateDeformatter(AsymmetricAlgorithm key)
        {
            if (key == null)
                throw new ArgumentNullException("key");

            RSAPKCS1SignatureDeformatter deformatter = new RSAPKCS1SignatureDeformatter(key);
            deformatter.SetHashAlgorithm("SHA256");
            return deformatter;
        }

        public override AsymmetricSignatureFormatter CreateFormatter(AsymmetricAlgorithm key)
        {
            if (key == null)
                throw new ArgumentNullException("key");

            RSAPKCS1SignatureFormatter formatter = new RSAPKCS1SignatureFormatter(key);
            formatter.SetHashAlgorithm("SHA256");
            return formatter;
        }
    }
}

在您的设置区域(尽早)添加以下内容:

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

关于c# - 如何在 ASP.NET CORE 中签署 XML SAML 断言,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47264109/

相关文章:

c# - 什么时候应该将任务视为 "long running"?

c# - 为什么 Asp.net MVC 不能区分具有不同参数的两个 Action ?

java - 我应该在哪里放置字段/方法注释?

asp.net - 使用 ASP.NET 如何从网站读取外部 XML?

Java 创建一个新的 xml 文件并附加它

c# - 无法构建带有 project.json 的 .NET 项目

c# - App.Config 中使用哪种编码?

c# - 在 C# 中的存储过程中使用全局临时表

asp.net - 在 ASP.NET 面板中查找所有控件?

asp.net - 在中继器控制中显示 2 个小数位