首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SignedXml校验签名返回false

SignedXml校验签名返回false
EN

Stack Overflow用户
提问于 2010-10-15 00:59:41
回答 4查看 15.1K关注 0票数 10

我在这里看过关于这个问题的其他帖子,似乎没有一个能解决我的问题。

上周我一直在尝试验证一个SAML断言,我有两个客户给我发送了SAML,但我无法验证它。

主要的过程是我们得到一个base64编码的断言,然后我解码它。将其加载到PreserveWhitespace = true的XmlDocment中。

验证方法为

代码语言:javascript
复制
  public static bool Verify(X509Certificate2 cert, XmlElement xmlElement, SignedXml signedXml)
  {
       bool flag;
       try
       {
           KeyInfo keyInfo = new KeyInfo();
           var clause = new KeyInfoX509Data(cert);
           keyInfo.AddClause(clause);

            XmlElement signatureElement = GetSignatureElement(xmlElement);
            if (signatureElement == null)
            {
                string message = "The XML does not contain a signature.";
                throw new SAMLSignatureException(message);
            }
            signedXml.LoadXml(signatureElement);
            if (keyInfo != null)
            {
                signedXml.KeyInfo = keyInfo;
            }
            SetSigningKeyFromKeyInfo(signedXml);
            flag = signedXml.CheckSignature(cert.PublicKey.Key);
        }
        catch (Exception exception)
        {
            throw new SAMLSignatureException("Failed to verify the XML signature.", exception);
        }
        return flag;
    }

 private static void SetSigningKeyFromKeyInfo(SignedXml signedXml)
    {
        IEnumerator enumerator = signedXml.KeyInfo.GetEnumerator();
        while (enumerator.MoveNext())
        {
            if (enumerator.Current is KeyInfoX509Data)
            {
                var current = (KeyInfoX509Data) enumerator.Current;
                if (current.Certificates.Count != 0)
                {
                    var certificate = (X509Certificate) current.Certificates[0];
                    var certificate2 = new X509Certificate2(certificate);
                    AsymmetricAlgorithm key = certificate2.PublicKey.Key;
                    signedXml.SigningKey = key;
                    return;
                }
            }
            else
            {
                if (enumerator.Current is RSAKeyValue)
                {
                    var value2 = (RSAKeyValue) enumerator.Current;
                    signedXml.SigningKey = value2.Key;
                    return;
                }
                if (enumerator.Current is DSAKeyValue)
                {
                    var value3 = (DSAKeyValue) enumerator.Current;
                    signedXml.SigningKey = value3.Key;
                    return;
                }
            }
        }
        throw new SAMLSignatureException("No signing key could be found in the key info.");
    }

我有来自客户机的证书,我从Web.Config (它存储为base64编码的字符串)中读取了证书,xmlelement是签名元素,signedXml是用新的SignedXml(xmlElement)创建的SignedXml对象。

两个客户机都得到了checksignature返回的false,但是当我用我的证书创建自己的签名saml时,它将返回true。

这里我漏掉了什么?

编辑:是的,两个客户端都在Java上,我发布了SetSigningKeyFromKeyInfo方法

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-09-29 14:54:36

在过去,我处理过很多带签名的XML。我只能说那是一场噩梦。基本上,当您对XML进行签名时,它将经历一个称为规范化(C14N)的过程。它需要将XML文本转换为可签名的字节流。C14N标准中的空格和名称空间处理等很难理解,甚至更难正确实现。甚至还有多种类型的C14N。

.NET实现对于它接受的内容是非常有选择性的。您的其他实现很可能与.NET实现的工作方式不完全相同。这实在是非常可悲的。例如,如果您可以在签名之前消除源XML中的空格和名称空间,这可能会有所帮助。此外,如果您可以确保两个实现使用相同的C14N设置。

否则,许多调试工作都在等待着您。您可以调试到框架中,或者使用反射手动调用其内部方法,以查看它是如何计算XML片段和签名的。并对其他实现执行相同的操作。基本上,您需要查看在这两种情况下签名的确切字节流。这是签名前转换的最后一步。如果这些字节流匹配,那么根据我的经验,RSA签名部分不会有任何问题。如果它们不匹配,就像您的情况一样,至少您会看到问题所在。

票数 9
EN

Stack Overflow用户

发布于 2016-05-13 16:13:33

我只是遇到了类似的问题,浪费了很多时间,也许这能帮助到一些人。

我的环境是100% .Net 4.5,并且我的代码只使用SignedXml类。但是SAML断言在一个地方被接受,在另一个地方被拒绝。

原来一个地方是通过用PreserveWhitespace = true初始化的XmlDocument实例加载断言,而另一个地方没有。

而且断言打印得很漂亮,所以它有回车符和大量的缩进空格。删除所有回车符和缩进空格修复了我的问题。

票数 5
EN

Stack Overflow用户

发布于 2018-07-20 18:26:58

Saml和Timore也有类似的问题。Saml需要从Base64中解码,但首先我使用:

代码语言:javascript
复制
var saml = System.Text.Encoding.Default.GetString(Convert.FromBase64String(samlToken))

但这使用了ASCII解码,并且在处理特殊字符时遇到了问题。这意味着XML与签名时略有不同,这就是它失败的原因。将其更改为:

代码语言:javascript
复制
var saml = System.Text.Encoding.UTF8.GetString(Convert.FromBase64String(samlToken))

它对所有的案例都有效。

因此,请确保您使用了正确的编码!

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3935600

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档