2010-10-14 11 views
9

मैंने इस मुद्दे के बारे में अन्य पोस्टों को देखा है और उनमें से कोई भी मेरी स्थिति को संबोधित नहीं कर रहा है।साइनएडएक्सएमएल चेकसिग्नेचर झूठी

मैं पिछले सप्ताह के लिए एक saml कथन की पुष्टि करने की कोशिश कर दिया गया है और मैं 2 ग्राहकों है कि मुझे SAML भेज दिया है, लेकिन मैं इसे सत्यापित नहीं कर सकता।

मुख्य प्रक्रिया हम एक बेस 64 इनकोडिंग जोर मिलता है और मैं इसे डिकोड है। PreserveWhitespace = true के साथ इसे XmlDocment में लोड करें।

को सत्यापित विधि

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 (अपने संग्रहीत के रूप में बेस 64 इनकोडिंग स्ट्रिंग) XmlElement पर हस्ताक्षर किए तत्व है से पढ़ने से प्रमाण पत्र है, signedXml एक SignedXml वस्तु है कि नई SignedXml (XmlElement)

दोनों ग्राहकों झूठी checksignature द्वारा वापस मिलता है लेकिन जब मैं अपने प्रमाण पत्र के साथ अपने ही हस्ताक्षर किए saml बनाने यह सच वापस आ जाएगी साथ बनाया गया था।

मुझे यहां क्या याद आ रही है?

संपादित करें: हाँ ग्राहकों के दोनों जावा पर हैं और मैं SetSigningKeyFromKeyInfo विधि

+1

मुझे लगता है कि आपको प्राप्त होने वाला दावा जावा जैसी गैर-नेटवर्क्स भाषा में उत्पन्न हुआ है? –

+0

'SetSigningKeyFromKeyInfo (signXml) क्या करता है;' क्या करें? –

+0

जब आपके पास आधार 64 डीकोडेड किया गया है, तो क्या आप एक्सएमएल को फ़ाइल में डंप कर सकते हैं और इसकी तुलना में अपने स्वयं के दावों में से एक (सूक्ष्म) संरचनात्मक असंगतताओं की जांच कर सकते हैं? –

उत्तर

7

मैं हस्ताक्षरित XML के साथ निपटा अतीत में एक बहुत कुछ है तैनात। मैं बस इतना कह सकता हूं कि यह एक दुःस्वप्न था। असल में, जब आप एक्सएमएल पर हस्ताक्षर करते हैं, तो यह कैनोनिकललाइजेशन (सी 14 एन) नामक प्रक्रिया के माध्यम से जाता है। इसे एक्सएमएल टेक्स्ट को बाइट स्ट्रीम में बदलना होगा जिसे हस्ताक्षर किया जा सकता है। व्हाइटस्पेस & एक्सएमएल सी 14 एन मानकों में, दूसरों के बीच नामस्थान हैंडलिंग, समझने में कठिनाई होती है, यहां तक ​​कि सही लागू करने के लिए भी कठिन है। सी 14 एन के कई प्रकार भी हैं।

नेट कार्यान्वयन यह क्या स्वीकार करता है के बारे में बहुत चयनात्मक है। यह काफी संभव है कि आपका अन्य कार्यान्वयन ठीक उसी तरह काम नहीं करता है जैसे .NET एक। यह वास्तव में बहुत दुखी है। यदि आप हस्ताक्षर करने से पहले अपने स्रोत एक्सएमएल से व्हाइटस्पेस और नेमस्पेस को खत्म कर सकते हैं, उदाहरण के लिए, इससे मदद मिल सकती है। इसके अलावा यदि आप यह सुनिश्चित कर सकते हैं कि दोनों कार्यान्वयन समान C14N सेटिंग्स का उपयोग करते हैं।

अन्यथा डिबगिंग का एक बहुत आप इंतजार कर रहा है। आप ढांचे में डीबग कर सकते हैं, या प्रतिबिंब के साथ अपने आंतरिक तरीकों को कॉल कर सकते हैं, यह देखने के लिए कि यह XML खंड और हस्ताक्षर की गणना कैसे करता है। और अन्य कार्यान्वयन के साथ भी ऐसा ही करें। असल में आपको सटीक बाइट स्ट्रीम देखना होगा जो दोनों मामलों में हस्ताक्षरित हैं। हस्ताक्षर करने से पहले यह रूपांतरण का अंतिम चरण है। यदि वे बाइट स्ट्रीम मिलते हैं, तो आपको मेरे अनुभव में आरएसए हस्ताक्षर भाग में कोई समस्या नहीं होगी। यदि वे आपके मामले में नहीं हैं, तो कम से कम आप देखेंगे कि समस्या कहां है।

+4

के लिए utf-16 है, मैं वास्तव में चाहता हूं कि यह सही उत्तर न हो। – Hovis

1

मैं सिर्फ एक समान मुद्दा था और बहुत समय खो दिया है, हो सकता है यह किसी की मदद कर सकते हैं।

मेरा पर्यावरण 100% है .Net 4.5, और मेरा कोड केवल साइनएडएक्सएमएल वर्ग का उपयोग करता है। लेकिन एक एसएएमएल दावे को एक ही स्थान पर स्वीकार कर लिया गया और उसने एक और से इनकार कर दिया।

यह पता चला कि एक स्थान PreserveWhitespace = true के साथ प्रारंभ किए गए XmlDocument उदाहरण के माध्यम से दावा लोड कर रहा था, जबकि दूसरा नहीं था।

और दावा बहुत प्रिंट किया गया था, इसलिए इसमें कैरिज रिटर्न और बहुत से इंडेंटेशन रिक्त स्थान थे। सभी कैरिज रिटर्न हटाने और इंडेंटेशन रिक्त स्थान को मेरे मुद्दे को ठीक किया गया।

संबंधित मुद्दे