代码之家  ›  专栏  ›  技术社区  ›  Ahmad

RSASSA-PSS,无参数,使用SHA-256.Net 4.5支持

  •  7
  • Ahmad  · 技术社区  · 11 年前

    我正在尝试使用System.Security.Cryptography(目标框架.NET 4.5)创建xml数字签名,到目前为止,我使用以下方案创建并验证了签名: RSA PKCS#1 v1.5和SHA-256: http://www.w3.org/2001/04/xmldsig-more#rsa-sha256

    但是,我无法使用以下方案: 使用SHA-256[RFC6931]无参数的RSASSA-PSS: http://www.w3.org/2007/05/xmldsig-more#sha256-rsa-MGF1

    显示的错误是明确的“无法为提供的签名算法创建SignatureDescription”

    对于“RSA PKCS#1 v1.5和SHA-256”,我添加了以下公共类作为其签名:

       public class RSAPKCS1SHA256SignatureDescription : SignatureDescription
       {
            public RSAPKCS1SHA256SignatureDescription()
            {
                base.KeyAlgorithm = "System.Security.Cryptography.RSACryptoServiceProvider";
                base.DigestAlgorithm = "System.Security.Cryptography.SHA256Managed";
                base.FormatterAlgorithm = "System.Security.Cryptography.RSAPKCS1SignatureFormatter";
                base.DeformatterAlgorithm = "System.Security.Cryptography.RSAPKCS1SignatureDeformatter";
            }
    
            public override AsymmetricSignatureDeformatter CreateDeformatter(AsymmetricAlgorithm key)
            {
                AsymmetricSignatureDeformatter asymmetricSignatureDeformatter = (AsymmetricSignatureDeformatter)
                CryptoConfig.CreateFromName(base.DeformatterAlgorithm);
                asymmetricSignatureDeformatter.SetKey(key);
                asymmetricSignatureDeformatter.SetHashAlgorithm("SHA256");
                return asymmetricSignatureDeformatter;
            }
        }
    

    然而,我不知道.Net 4.5是否支持使用SHA-256不带参数的RSASSA-PSS,如果支持,如何设置其签名定义。

    如果有人有类似的经历并能提供一些帮助,我将非常感谢。

    1 回复  |  直到 11 年前
        1
  •  3
  •   Timo    6 年前

    我终于想通了。诀窍是注册XML签名指定的算法,在我的情况下” http://www.w3.org/2007/05/xmldsig-more#sha256-rsa-MGF1 “.将其注册到自定义类,该类使用自定义签名格式化程序和变形程序 RSASignaturePadding.Pss .

    下面是一个实现,您只需调用 RsaSsaPss.RegisterSha256RsaMgf1() 一次,例如从客户端的静态构造函数。然后 SignedXml.CheckSignature() SignedXml.ComputeSignature() 自动适用于指定此算法的任何XML签名。

    在核心2.1和框架4.7.1上测试:

    /// <summary>
    /// Contains classes for using RSA-SSA-PSS, as well as methods for registering them.
    /// Registering such types adds support for them to SignedXml.
    /// </summary>
    public class RsaSsaPss
    {
        /// <summary>
        /// Registers an implementation for "http://www.w3.org/2007/05/xmldsig-more#sha256-rsa-MGF1".
        /// </summary>
        public static void RegisterSha256RsaMgf1()
        {
            CryptoConfig.AddAlgorithm(typeof(RsaPssSha256SignatureDescription), "http://www.w3.org/2007/05/xmldsig-more#sha256-rsa-MGF1");
        }
    
        // Can add further registrations here...
    
        public class RsaPssSha256SignatureDescription : SignatureDescription
        {
            public RsaPssSha256SignatureDescription()
            {
                using (var rsa = RSA.Create())
                {
                    this.KeyAlgorithm = rsa.GetType().AssemblyQualifiedName; // Does not like a simple algorithm name, but wants a type name (AssembyQualifiedName in Core)
                }
                this.DigestAlgorithm = "SHA256"; // Somehow wants a simple algorithm name
                this.FormatterAlgorithm = typeof(RsaPssSignatureFormatter).FullName;
                this.DeformatterAlgorithm = typeof(RsaPssSignatureDeformatter).FullName;
            }
    
            public override AsymmetricSignatureFormatter CreateFormatter(AsymmetricAlgorithm key)
            {
                var signatureFormatter = new RsaPssSignatureFormatter();
                signatureFormatter.SetKey(key);
                signatureFormatter.SetHashAlgorithm(this.DigestAlgorithm);
                return signatureFormatter;
            }
    
            public override AsymmetricSignatureDeformatter CreateDeformatter(AsymmetricAlgorithm key)
            {
                var signatureDeformatter = new RsaPssSignatureDeformatter();
                signatureDeformatter.SetKey(key);
                signatureDeformatter.SetHashAlgorithm(this.DigestAlgorithm);
                return signatureDeformatter;
            }
    
            public class RsaPssSignatureFormatter : AsymmetricSignatureFormatter
            {
                private RSA Key { get; set; }
                private string HashAlgorithmName { get; set; }
    
                public override void SetKey(AsymmetricAlgorithm key)
                {
                    this.Key = (RSA)key;
                }
    
                public override void SetHashAlgorithm(string strName)
                {
                    // Verify the name
                    Oid.FromFriendlyName(strName, OidGroup.HashAlgorithm);
    
                    this.HashAlgorithmName = strName;
                }
    
                public override byte[] CreateSignature(byte[] rgbHash)
                {
                    return this.Key.SignHash(rgbHash, new HashAlgorithmName(this.HashAlgorithmName), RSASignaturePadding.Pss);
                }
            }
    
            public class RsaPssSignatureDeformatter : AsymmetricSignatureDeformatter
            {
                private RSA Key { get; set; }
                private string HashAlgorithmName { get; set; }
    
                public override void SetKey(AsymmetricAlgorithm key)
                {
                    this.Key = (RSA)key;
                }
    
                public override void SetHashAlgorithm(string strName)
                {
                    // Verify the name
                    Oid.FromFriendlyName(strName, OidGroup.HashAlgorithm);
    
                    this.HashAlgorithmName = strName;
                }
    
                public override bool VerifySignature(byte[] rgbHash, byte[] rgbSignature)
                {
                    return this.Key.VerifyHash(rgbHash, rgbSignature, new HashAlgorithmName(this.HashAlgorithmName), RSASignaturePadding.Pss);
                }
            }
        }
    }