Frage

Ich habe mir andere Beiträge hier zu diesem Problem angesehen und keiner von ihnen scheint meine Situation zu behandeln.

Ich habe versucht, eine SAML -Behauptung in der letzten Woche zu überprüfen, und ich habe 2 Kunden, die mir SAML geschickt haben, aber ich kann sie nicht überprüfen.

Der Hauptprozess ist, dass wir eine base64 -codierte Behauptung erhalten und ich sie entschlüsseln kann. Laden Sie es in ein xmldocment mit PreserveWhiteSpace = true.

Die Verify -Methode ist

  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.");
    }

Ich habe das Zertifikat des Clients, das ich von web.config (es als Basis64 -codierte Zeichenfolge gespeichert habe) XMLElement ist das signierte Element, SignEdXML, ein signedxml -Objekt, das mit neu signedxml (xmlelement) erstellt wurde, ist.

Beide Kunden werden durch Checksignaturen falsch zurückgegeben, aber wenn ich mit meinem Zertifikat meine eigene SAML erstelle, wird es true zurückgegeben.

Was vermisse ich hier?

Bearbeiten: Ja, beide Kunden sind auf Java und ich habe die SetSigningKeyFromKeyInfo -Methode gepostet

War es hilfreich?

Lösung

Ich habe mich in der Vergangenheit sehr unterschrieben. Ich kann nur sagen, dass es ein Albtraum war. Wenn Sie XML unterschreiben, durchläuft es im Grunde einen Prozess, der als Canonicalisierung (C14N) bezeichnet wird. Es muss den XML -Text in einen Byte -Stream verwandeln, der signiert werden kann. Die Handhabung des Whitespace & Namespace -Umgangs unter anderem in XML C14N -Standards sind schwer zu verstehen, noch schwerer zu implementieren. Es gibt sogar mehrere Arten von C14N.

Die .NET -Implementierung ist sehr selektiv in Bezug auf das, was sie akzeptiert. Es ist durchaus möglich, dass Ihre andere Implementierung nicht genauso funktioniert wie die .NET. Das ist in der Tat sehr traurig. Wenn Sie Whitespace und Namespaces aus Ihrer Quelle XML entfernen können, kann dies beispielsweise helfen. Auch wenn Sie sicherstellen können, dass beide Implementierungen die gleichen C14N -Einstellungen verwenden.

Ansonsten erwartet Sie viel Debugging. Sie können in das Framework debuggen oder seine internen Methoden von Hand mit Reflexion aufrufen, um zu sehen, wie es das XML -Fragment und die Signatur berechnet. Und dasselbe mit der anderen Implementierung tun. Grundsätzlich müssen Sie die genauen Byte -Streams sehen, die in beiden Fällen signiert sind. Dies ist der letzte Schritt der Konvertierung vor der Unterzeichnung. Wenn diese Byte -Streams übereinstimmen, haben Sie meiner Erfahrung keine Probleme mit dem RSA -Unterzeichnungsteil. Wenn diese nicht übereinstimmen, wie in Ihrem Fall, werden Sie zumindest sehen, wo sich das Problem befindet.

Andere Tipps

Ich hatte gerade ein ähnliches Problem und habe viel Zeit verloren, vielleicht kann dies jemandem helfen.

Meine Umgebung ist 100% .NET 4.5 und mein Code verwendet nur die signedxml -Klasse. Aber eine SAML -Behauptung wurde an einem Ort angenommen und bei einem anderen abgelehnt.

Stellte sich heraus PreserveWhitespace = true, während der andere nicht war.

Und die Behauptung war ziemlich gedruckt worden, so dass sie Kutschenrenditen und viele Eindringlinge hatte. Das Entfernen aller Wagenrenditen und die Eindringräume behoben mein Problem.

Hatte ein ähnliches Problem mit SAML als Timores. Die SAML musste von Base64 dekodiert werden, aber zuerst benutzte ich:

var saml = System.Text.Encoding.Default.GetString(Convert.FromBase64String(samlToken))

Aber dies verwendete ASCII -Dekodierung und hatte Probleme mit Sonderzeichen. Was bedeutet, dass der XML etwas anders war als bei der Unterschrift, und deshalb ist es gescheitert. Änderte es in:

var saml = System.Text.Encoding.UTF8.GetString(Convert.FromBase64String(samlToken))

Und es hat für alle Fälle funktioniert.

Stellen Sie also sicher, dass Sie die richtige Codierung verwenden!

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top