2011-01-12 7 views
5

पर एक्स.50 9 प्रमाण पत्र का उपयोग करके SOAP संदेशों को साइन करना यह वेब पर मेरा पहला प्रश्न है। उम्मीद है कि यह समझ में आता है।डब्ल्यूसीएफ सेवा से जावा webservice

मैंने वेब पर इस मुद्दे से संबंधित कई ब्लॉग देखे हैं, और मैंने बिना किसी सफलता के प्रस्तुत किए गए कुछ विचारों की कोशिश की है। यहां मेरी स्थिति है:

मेरे पास एक वेब ऐप है जो डब्ल्यूसीएफ वेब सेवा को कॉल करता है जो फिर जावा वेब सेवा को कॉल करता है। वे सभी अलग-अलग सर्वर पर हैं। जावा वेब सेवा के लिए डब्ल्यूसीएफ वेब सेवा के बीच कॉल https से अधिक नहीं है क्योंकि प्रमाणपत्र कॉलर की पहचान करने के लिए पर्याप्त होगा (इसलिए संदेश सुरक्षा)।

  • जावा वेब सेवा (ब्लैक बॉक्स)

जावा वेब सेवा प्राप्त एक हस्ताक्षरित संदेश के लिए की आवश्यकता है और नीचे के अनुसार काम करता है: इससे पहले कि प्रत्येक अनुरोध हैंडलर अवरोध आने वाले सभी संदेशों संसाधित किया जाता है
और निम्नलिखित सत्यापन नियमों को निष्पादित करता है:
1. क्या संदेश में सुरक्षा शीर्षलेख
2. क्या संदेश में सही सुरक्षा शीर्षलेख आईडी
है , विन्यास आधारित
6. प्रमाणपत्र मान्य (समाप्त नहीं हुआ है - 10 3. संदेश सही ढंग से हस्ताक्षर किए गए
4. संदेश एक KeyInfo x.509 प्रमाणपत्र
5. एक विश्वसनीय सीए से जारी प्रमाणपत्र है उपयोग किया गया है है रद्द कर दिया)
7. प्रमाण पत्र सही नीति OID

एक बार इन चरणों के सभी तो पुष्टि की गई है संदेश, संसाधित किया जा सकता किसी भी कदम विफल रहता है तो एक साबुन संदेश अपवाद लौटा दी जाएगी उपयोग किया गया है।

एसओएपी सुरक्षा शीर्षलेख xxx के खिलाफ मान्य होना चाहिए ... w3.org/TR/SOAP-dsig/ डिजिटल हस्ताक्षर विनिर्देश।

सबसे पूरा विवरण यहां xxx पाया जा सकता है ... ibm.com/developerworks/webservices/library/ws-security.html यह आईबीएम आलेख प्रत्येक डब्ल्यूएस-सुरक्षा शीर्षलेख के विवरण सूचीबद्ध करता है, इसके अतिरिक्त एक नमूना हस्ताक्षर किए गए SOAP संदेश दे दी गयी।

एसओएपी संदेश पर हस्ताक्षर करते समय आपको संदेश में x.50 9 प्रमाण पत्र भी जोड़ना होगा KeyInfo प्रमाण पत्र सत्यापन के लिए यह आवश्यक है।

सोप अनुरोध यह पसंद चाहिए:

<?xml version="1.0" encoding="UTF-8"?> 
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"> 
<S:Header> 
<ds:Signature xmlns:ds="xxx...w3.org/2000/09/xmldsig#" Id="Signature001"> 
<ds:SignedInfo> 
<ds:CanonicalizationMethod Algorithm="xxx...w3.org/TR/2001/REC-xml-c14n-20010315"/> 
<ds:SignatureMethod Algorithm="xxx...w3.org/2000/09/xmldsig#rsa-sha1"/> 
<ds:Reference URI=""> 
<ds:Transforms> 
<ds:Transform Algorithm="xxx...w3.org/2000/09/xmldsig#enveloped-signature"/> 
</ds:Transforms> 
<ds:DigestMethod Algorithm="xxx...w3.org/2000/09/xmldsig#sha1"/> 
<ds:DigestValue>soe1PnaGXVGrsauC61JSHD+uqGw=</ds:DigestValue> 
</ds:Reference> 
<ds:Reference URI="#KeyInfo001"> 
<ds:DigestMethod Algorithm="xxx...w3.org/2000/09/xmldsig#sha1"/> 
<ds:DigestValue>Y9SRPQ9TcDu+GazO3LFwodEdhaA=</ds:DigestValue> 
</ds:Reference> 
</ds:SignedInfo> 
<ds:SignatureValue>jBX/8XkY2aCte7qgXEp1sbNWmQcK/90iVL58sAvwYAEcBABGzOk2agxR0HvWrNa6ixkocAQ205lggwOxnxZJvoVozVYAAjcLtayPBOUYrnSEBFrwKWP/vxgvUDRIdXeIuw5GLY87NrTQMm1Ehf/HvMX9hTBJn4Nm8RdDiUmPcIo=</ds:SignatureValue> 
<ds:KeyInfo Id="KeyInfo001"> 
<ds:X509Data> 
<ds:X509Certificate>MIIEbZCCA1WgAwIBAgIES1XpMjANBgkqhkiG9w0BAQUFADBYMRUwEwYKCZImiZPyLGQBGRYFbG9jYWwxFzAVBgoJkiaJk/IsZAEZFgdlbnRydXN0MRIwEAYDVQQDEwllbnRydXN0U00xEjAQBgNVBAMTCWVudHJ1c3RDQTAeFw0xMDA0MjIxMDQ4MDBaFw0xMzA0MjIxMTE4MDBaMGoxFTATBgoJkiaJk/IsZAEZFgVsb2NhbDEXMBUGCgmSJomT8ixkARkWB2VudHJ1c3QxEjAQBgNVBAMTCWVudHJ1c3RTTTESMBAGA1UEAxMJZW50cnVzdENBMRAwDgYDVQQDEwdSYnMgUmJzMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDMf88L2JjLPG1hNmTA/KBiC53WVwS2WU9Jh3lC1Rob6RMzOojomZ/dNrvSRB6nzWeXJpZXwik4XFrsAq24By2SZpLTO4p8Vcq71mTAfDu33cnO49Au2pwNvcMn5qIKBk1Xx+oVb4fzK9ncTRu7bW46HsIYth+qkGhbI2JEHwr/zwIDAQABo4IBrzCCAaswCwYDVR0PBAQDAgeAMCsGA1UdEAQkMCKADzIwMTAwNDIyMTA0ODAwWoEPMjAxMjA1MjgxNTE4MDBaMCMGA1UdIAQcMBowCwYJYIZIAYb6awoEMAsGCSqGSIb2fQdLAzAbBgNVHQkEFDASMBAGCSqGSIb2fQdEHTEDAgEBMIHGBgNVHR8Egb4wgbswb6BtoGukaTBnMRUwEwYKCZImiZPyLGQBGRYFbG9jYWwxFzAVBgoJkiaJk/IsZAEZFgdlbnRydXN0MRIwEAYDVQQDEwllbnRydXN0U00xEjAQBgNVBAMTCWVudHJ1c3RDQTENMAsGA1UEAxMEQ1JMMTBIoEagRIZCZmlsZTovLy8vTVNJREhVLTQ0NUE0RkVFL0NSTC9lbnRydXN0Y2FfZW50cnVzdHNtX2xvY2FsX2NybGZpbGUuY3JsMB8GA1UdIwQYMBaAFBvSL6cPz8L5shubV58yf0pczKzuMB0GA1UdDgQWBBT1/j6OSS8FTjwqluvew16sv7h+VzAJBgNVHRMEAjAAMBkGCSqGSIb2fQdBAAQMMAobBFY4LjADAgSwMA0GCSqGSIb3DQEBBQUAA4IBAQBXxRIA4HUvGSw4L+4uaR51pY4ISjUQWo2Fh7FYBMt29NsKCTdur1OWVVdndt1yjXP4yWXxoAhHtvZL+XNALUFlR2HAWiXuL1nRcxHkB98N5gPqQzW/lJk9cLtL4hVp28EiEpgmKT3I3NP2Pdb2G5MMOdvQ/GFb2y6OwblR8ViPQ8B2aHWzXMrH+0qadPAuBhXyAohwb+mMuYT/ms6xpGi1NMYuYMf6XONz9GkZgnGnMwa+9CCQws1HNz8WYHtmFIxLsVuEWc/0a1vg4IYX1Ds/ttyhJGTVXOSJSkBz8kRyj1pNBDdc1KeG8M++O8m8VgRTJvYaPc7NMiclISukGpea</ds:X509Certificate> </ds:X509Data> 
</ds:KeyInfo> 
</ds:Signature> 
</S:Header> 
<S:Body Id="ABC"> 
<ns2:createUser xmlns:ns2="http://webservice.rbs.emea.ps.entrust.com/" xmlns:ns3="http://webservice.rbs.emea.ps.entrust.com/types/CertificateException" xmlns:ns4="http://webservice.rbs.emea.ps.entrust.com/types/UserException"> 
<userID>0061020051</userID> 
</ns2:createUser> 
</S:Body> 
</S:Envelope> 
  • WCF वेब सेवा

मैं एक सर्वर प्रमाणपत्र (एक विश्वस्त CA से P7B प्रारूप) है कि मैं स्थापित जहाँ मेरे WCF वेब सेवा वर्कस्टेशन (देव) एमएमसी प्रमाणपत्र स्नैप-इन का उपयोग करके है (फिलहाल प्रमाणित प्रकाशकों में प्रमाणित है)। मुझे नहीं लगता कि मुझे जावा सर्वर पर एक और प्रमाण की आवश्यकता है क्योंकि प्रतिक्रिया स्पष्ट होनी चाहिए (न तो हस्ताक्षरित या एन्क्रिप्टेड)। मैं अभी भी इस प्रमाणपत्र पर थोड़ा उलझन में हूं- और सामान्य रूप से प्रमाण पत्र- क्योंकि ऐसा लगता है कि यह केवल एक सार्वजनिक कुंजी है।

यहां ऐप है।अपने परीक्षण परियोजना की config:

<client> 
    <endpoint address="http://entrust-user-certification-uat.fm.rbsgrp.net/rbs/WebAS" 
    behaviorConfiguration="endpointCredentialsBehavior" binding="wsHttpBinding" 
    bindingConfiguration="WebAsServicePortTypeBinding" contract="IWebAsServicePortType" 
    name="WebAsServicePortType"> 
    <!--<identity> 
     <dns value="entrust-user-certification-uat.fm.rbsgrp.net" /> 
    </identity>--> 
    </endpoint> 
</client> 
<bindings> 
    <wsHttpBinding> 
    <binding name="WebAsServicePortTypeBinding" closeTimeout="00:01:00" 
     openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" 
     bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" 
     maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Text" 
     textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false"> 
     <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" 
     maxBytesPerRead="4096" maxNameTableCharCount="16384" /> 
     <security mode="Message"> 
     <message clientCredentialType="Certificate" negotiateServiceCredential="false" 
      establishSecurityContext="false" /> 
     </security> 
    </binding> 
    </wsHttpBinding> 
</bindings> 

<behaviors> 
    <endpointBehaviors> 
    <behavior name="endpointCredentialsBehavior"> 
     <clientCredentials> 
     <clientCertificate findValue="entrust-user-certification-uat.fm.rbsgrp.net" 
      storeLocation="LocalMachine" storeName="TrustedPublisher" 
      x509FindType="FindBySubjectName"></clientCertificate> 
     <serviceCertificate> 
      <!-- 
      Setting the certificateValidationMode to PeerOrChainTrust means that if the certificate 
      is in the user's Trusted People store, then it will be trusted without performing a 
      validation of the certificate's issuer chain. This setting is used here for convenience so that the 
      sample can be run without having to have certificates issued by a certificate authority (CA). 
      This setting is less secure than the default, ChainTrust. The security implications of this 
      setting should be carefully considered before using PeerOrChainTrust in production code. 
      --> 
      <authentication certificateValidationMode="None" revocationMode="NoCheck" trustedStoreLocation="LocalMachine"/> 
     </serviceCertificate> 
     </clientCredentials> 
    </behavior> 
    </endpointBehaviors> 
</behaviors> 

जब मैं एक साधारण परीक्षण भागा:
          WebAS entrustService = नए WebAS();
          सक्रियण कोड प्रमाण कोड = entrustService.createUser ("testNomad");
          विफल रहा है:: System.Web.Services.Protocols.SoapException: javax.xml.soap.SOAPException:
मैं त्रुटि मिल गया है कोई हस्ताक्षर नहीं तत्व साबुन संदेश में पाया

कैसे कर सकते थे मैं प्रत्येक संदेश के लिए हस्ताक्षर प्रक्रिया को मजबूर करता हूं? मैं सोच रहा था कि मैं इसे आसानी से डब्ल्यूसीएफ कॉन्फ़िगरेशन के माध्यम से कर सकता हूं। किसी भी तरह की सहायता का स्वागत किया जाएगा !

+0

हाय Nomadefv, कैसे कर आप, IClientMessageInspector में/BeforeSendReques अनुरोध में अपने लौटे एक्सएमएल स्ट्रिंग इंजेक्षन? AJR –

+1

क्षमा करें। पिछले कुछ हफ्ते से थोड़ा सा। आप कोशिश कर सकते हैं: – Nomadefv

+0

'सार्वजनिक ऑब्जेक्ट पहले सेन्ड्रुवेस्ट (रेफ सिस्टम। सर्विसमोडेल.चैनल्स.मेजेज अनुरोध, सिस्टम। सर्विसमोडेल।IClientChannel चैनल) '{// ... सुरक्षित कॉन्फ़िगरेशन सेटिंग ' से भिन्न var प्राप्त करें // प्रमाणपत्र प्रमाणपत्र से प्रमाण पत्र लोड करें। 'X509Certificate2 प्रमाण = GetCertificateBySubject (प्रमाणपत्रसब्जेक्टनाम, प्रमाणपत्रस्टोरनाम, प्रमाणपत्रस्टोर स्थान); '// अनुरोध पर हस्ताक्षर करें ' स्ट्रिंग हस्ताक्षरित SoapMessage = SignRequest (request.ToString(), प्रमाणपत्र, हस्ताक्षर आईडी, keyInfoRefId, bodyId); – Nomadefv

उत्तर

14

ठीक है। कुछ प्रयासों और त्रुटियों के बाद यहां साइनएडएक्सएमएल और आईसीलिएंट मैसेज इंस्पेक्टर/फर्स्टसेन्डरक्वेट पैटर्न का उपयोग कर समाधान है। उनके प्रासंगिक सुझावों के लिए Yaron Naveh पर बहुत बहुत धन्यवाद।

// Sign an XML request and return it 
public static string SignRequest(string request, string SubjectName, string Signature, string keyInfoRefId) 
{ 
    if (string.IsNullOrEmpty(request)) 
     throw new ArgumentNullException("request"); 
    if (string.IsNullOrEmpty(SubjectName)) 
     throw new ArgumentNullException("SubjectName"); 

    // Load the certificate from the certificate store. 
    X509Certificate2 cert = GetCertificateBySubject(SubjectName); 

    // Create a new XML document. 
    XmlDocument doc = new XmlDocument(); 

    // Format the document to ignore white spaces. 
    doc.PreserveWhitespace = false; 

    // Load the passed XML 
    doc.LoadXml(request); 

    // Add the declaration as per Entrust sample provided -don't think it's necessary though 
    if (!(doc.FirstChild is XmlDeclaration)) 
    { 
     XmlDeclaration declaration = doc.CreateXmlDeclaration("1.0", "UTF-8", string.Empty); 
     doc.InsertBefore(declaration, doc.FirstChild); 
    } 

    // Remove the Action (MustUnderstand). 
    // TODO: Need to find a more elegant way to do so 
    XmlNode headerNode = null; 
    XmlNodeList nodeList = doc.GetElementsByTagName("Action"); 
    if (nodeList.Count > 0) 
    { 
     headerNode = nodeList[0].ParentNode; 
     headerNode.RemoveChild(nodeList[0]); 
    } 

    // Set the body id - not in used but could be useful at a later stage of this project 
    XmlNamespaceManager ns = new XmlNamespaceManager(doc.NameTable);  
    ns.AddNamespace("s", "http://schemas.xmlsoap.org/soap/envelope/"); 
    XmlElement body = doc.DocumentElement.SelectSingleNode(@"//s:Body", ns) as XmlElement;  
    if (body == null)  
     throw new ApplicationException("No body tag found"); 
    body.RemoveAllAttributes(); // no need to have namespace 
    body.SetAttribute("Id", "ABC"); // Body Id could be passed as a param 

    // Create a custom SignedXml object so that we could sign the keyinfo 
    CustomSignedXml signedXml = new CustomSignedXml(doc); 

    // Add the key to the SignedXml document. 
    signedXml.SigningKey = cert.PrivateKey; 

    // Create a new KeyInfo object. 
    KeyInfo keyInfo = new KeyInfo(); 
    keyInfo.Id = keyInfoRefId; 

    // Load the certificate into a KeyInfoX509Data object 
    // and add it to the KeyInfo object. 
    KeyInfoX509Data keyInfoData = new KeyInfoX509Data(); 
    keyInfoData.AddCertificate(cert); 
    keyInfo.AddClause(keyInfoData); 

    // Add the KeyInfo object to the SignedXml object. 
    signedXml.KeyInfo = keyInfo; 

    // Create a reference to be signed. 
    Reference reference = new Reference(); 
    reference.Uri = ""; 

    // Add an enveloped transformation to the reference. 
    XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform(); 
    reference.AddTransform(env); 

    // Add the reference to the SignedXml object. 
    signedXml.AddReference(reference); 

    Reference reference2 = new Reference(); 
    reference2.Uri = "#" + keyInfoRefId; 
    signedXml.AddReference(reference2); 

    // Add the Signature Id 
    signedXml.Signature.Id = Signature; 

    // Compute the signature. 
    signedXml.ComputeSignature(); 

    // Get the XML representation of the signature and save 
    // it to an XmlElement object. 
    XmlElement xmlDigitalSignature = signedXml.GetXml(); 

    // Append the Signature element to the XML document. 
    if (headerNode != null) 
    {     
     headerNode.AppendChild(doc.ImportNode(xmlDigitalSignature, true)); 
    } 

    return doc.InnerXml; 
} 

public static X509Certificate2 GetCertificateBySubject(string CertificateSubject) 
{ 
    // Check the args. 
    if (string.IsNullOrEmpty(CertificateSubject)) 
     throw new ArgumentNullException("CertificateSubject"); 

    // Load the certificate from the certificate store. 
    X509Certificate2 cert = null; 

    X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser); 

    try 
    { 
     // Open the store. 
     store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly); 

     // Find the certificate with the specified subject. 
     cert = store.Certificates.Find(X509FindType.FindBySubjectName, CertificateSubject, false)[0]; 

     // Throw an exception of the certificate was not found. 
     if (cert == null) 
     { 
      throw new CryptographicException("The certificate could not be found."); 
     } 
    } 
    finally 
    { 
     // Close the store even if an exception was thrown. 
     store.Close(); 
    } 

    return cert; 
} 

और CustomSignedXml वर्ग:

public class CustomSignedXml : SignedXml 
{ 
    public CustomSignedXml(XmlDocument doc) : base(doc) 
    { 
     return; 
    } 
    public override XmlElement GetIdElement(XmlDocument doc, string id) 
    { 
     // see if this is the key info being referenced, otherwise fall back to default behavior 
     if (String.Compare(id, this.KeyInfo.Id, StringComparison.OrdinalIgnoreCase) == 0) 
      return this.KeyInfo.GetXml(); 
     else 
      return base.GetIdElement(doc, id); 
    } 
} 
+0

हाय, यह मेरे लिए बहुत स्पष्ट नहीं है कि इसे पहले सेन्ड्रूक्वेट विधि में कैसे उपयोग करें। क्या आप समझा सकते हैं? –

0

क्या आप अपनी डब्लूसीएफ सेवा द्वारा संदेश भेज सकते हैं? Btw। डब्ल्यूएसडीएल में वर्णित जावा सेवा द्वारा उपयोग की जाने वाली संदेश सुरक्षा है - इससे चीजों को और अधिक आसान बना दिया जाएगा।

आपके विवरण से मुझे लगता है कि आपकी कॉन्फ़िगरेशन गलत है क्योंकि जब प्रमाणपत्र क्लाइंट क्रेडेंशियल्स का उपयोग किया जाता है तो आपको सार्वजनिक प्रमाणपत्र के साथ सार्वजनिक और निजी कुंजी और सर्वर प्रमाण पत्र के साथ दो प्रमाणपत्रों की आवश्यकता होती है।

यह भी शायद अपनी आवश्यकताओं में वर्णित है:

Does the message contain a KeyInfo x.509 certificate

Is the certificate issued from a trusted CA – configuration based

क्यों आप सेवा प्रमाण पत्र जो पहले से ही है कि सर्वर पर स्थापित किया गया है वापस भेजने के लिए की आवश्यकता होगी? सेवा जांच क्यों करनी चाहिए यदि उसका प्रमाणपत्र विश्वसनीय सीए से है? मुझे लगता है कि ये आवश्यकताएं कहती हैं कि आपको अपने क्लाइंट के लिए नया प्रमाणपत्र बनाना होगा।

लेकिन ये केवल धारणा हैं क्योंकि वास्तविक आवश्यकताओं को आम तौर पर साझा भाषा में वर्णित किया जाता है - डब्लूएसडीएल + डब्लूएस-सुरक्षा दावे।

कई स्तरों पर हस्ताक्षर और एन्क्रिप्शन नियंत्रित करना संभव है। सबसे पहले प्रत्येक ServiceContract और MessageContract में संपत्ति संरक्षण लेवल है जो डिफ़ॉल्ट रूप से EncryptAndSign है। आप इसे Sign में बदल सकते हैं।

+0

आपकी टिप्पणियों के लिए बहुत बहुत धन्यवाद! एक गंभीर दिन के बाद इस मुद्दे पर फिर से देखकर और जावा डेवलपर से बात करने के बाद, हमें वास्तव में क्लाइंट (डब्ल्यूसीएफ) पर केवल एक प्रमाण की आवश्यकता होनी चाहिए और इसके साथ सभी आउटगोइंग संदेशों पर हस्ताक्षर करना चाहिए। मैंने थोड़ा और देखा और IClientMessage इंस्पेक्टर को कार्यान्वित करने का समाधान हो सकता है। मैं अभी भी खुदाई कर रहा हूं ... – Nomadefv

+0

डब्ल्यूएसडीएल में जावा वीवी सेवा संदेश सुरक्षा का वर्णन नहीं किया गया है। अब आईसीलिएंट मैसेज इंस्पेक्टर और फर्स्टसेन्ड रिक्वेस्ट पर देख रहे हैं। – Nomadefv