سؤال

بحاجة إلى بعض التوجيه.

لدي تطبيق Java WebStart وأريد الاتصال بخادم عبر ssl. فقط إضافة خاصية مثل: System.SetProperty ("javax.net.ssl.truststore" ، "my.keystore") ؛ ولكن منذ برنامج Jaws تم تنزيله من الخادم لم ينجح وليس لديه my.keystore على نظام الملفات المحلي. لذلك قررت توزيع الشهادة على جميع العملاء. لقد فعلت ما يلي وعملت.

  1. اقرأ هذا المتجر الثقة على أنه دفق (استخدم طريقة getResourCeasStream).
  2. احفظه في أي ملف على جهاز العميل (Sometemp)
  3. Call System.SetProperty ("javax.net.ssl.truststore" ، TrustStorePath) ؛

لكنني متأكد من أنه يجب أن يكون هناك حلول أفضل من هذا .. أي أفكار تجعلها أفضل؟

public boolean validateUserFromActiveDirectory(String userId) {
                    final String MEMBER_GROUP = "CN=asdadasd,OU=asdasdasd Accounts,OU=adasdas,OU=asdasdas,DC=asdasdas,DC=asdasdas,DC=adasdasd,DC=asdasdasd";
            String employeeNumber = "";
            final String LDAP_INIT_CTX = "com.sun.jndi.ldap.LdapCtxFactory";
            final String LDAP_URL = "ldap://xx-ssssssss.eee.eee.eeeee.eeeee:636";
            final String MY_ATTRS[] = { "employeeNumber" };
            String adminPassword = "somepassword";
            String securityProtocol = "ssl";
            boolean isValidUser = false;
            try {

                  Hashtable env = new Hashtable();
                  env.put(Context.INITIAL_CONTEXT_FACTORY, LDAP_INIT_CTX);
                  env.put(Context.PROVIDER_URL, LDAP_URL);
                  env.put(Context.SECURITY_AUTHENTICATION, "simple");
                  env.put(Context.REFERRAL, "follow");
                  env.put(Context.SECURITY_PRINCIPAL, MEMBER_GROUP);
                  env.put(Context.SECURITY_CREDENTIALS, adminPassword);
                  env.put(Context.SECURITY_PROTOCOL, securityProtocol);

            //C:\Documents and Settings\yourusername\Local Settings\Temp
            File tf = File.createTempFile("someTruststore", ".jks");
            tf.deleteOnExit();
            byte buffer[] = new byte[0x1000];
               ClassLoader cl = JNDI.class.getClassLoader();
            InputStream in = cl.getResourceAsStream(
                    "someTruststore.jks");
            FileOutputStream out = new FileOutputStream(tf);
            int cnt;
            while ((cnt = in.read(buffer)) != -1)
                out.write(buffer, 0, cnt);
            in.close();
            out.close();
            System.setProperty("javax.net.ssl.trustStore", tf
                            .getAbsolutePath());

                  DirContext context = new InitialLdapContext(env, null);
                  SearchControls searchControls = new SearchControls();
                  searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
                  NamingEnumeration results = context.search(
                              "XX=ent,XX=abc,XX=aaaaa,XX=aaaa", "(sAMAccountName="
                                          + userId + ")", searchControls);

                  if (results != null && results.hasMore()) {
                      //some logic

                        }
                  }
            } catch (Exception e) {
                  e.printStackTrace();
            }
            return isValidUser;
      }

-Padur ============================ ** ==============

/**

* */

package util;

/**
 * @author spaduri
 *
 */
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;

import javax.net.SocketFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;

public class CustomSSLSocketFactory extends SSLSocketFactory {

    private SSLSocketFactory factory;

    public CustomSSLSocketFactory() {
        try {
            SSLContext sslcontext = null;
              // Call getKeyManagers to get suitable key managers
            KeyManager[] kms=getKeyManagers();
            if (sslcontext == null) {
                sslcontext = SSLContext.getInstance("SSL");
                sslcontext.init(kms,
                new TrustManager[] { new CustomTrustManager() },
                new java.security.SecureRandom());
            }
            factory = (SSLSocketFactory) sslcontext.getSocketFactory();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }


    public static SocketFactory getDefault() {
        return new CustomSSLSocketFactory();
    }

    public Socket createSocket(Socket socket, String s, int i, boolean flag) throws IOException {
        return factory.createSocket(socket, s, i, flag);
    }

    public Socket createSocket(InetAddress inaddr, int i, InetAddress inaddr1, int j) throws IOException {
        return factory.createSocket(inaddr, i, inaddr1, j);
    }

    public Socket createSocket(InetAddress inaddr, int i) throws IOException {
        return factory.createSocket(inaddr, i);
    }

    public Socket createSocket(String s, int i, InetAddress inaddr, int j) throws IOException {
        return factory.createSocket(s, i, inaddr, j);
    }

    public Socket createSocket(String s, int i) throws IOException {
        return factory.createSocket(s, i);
    }

    public String[] getDefaultCipherSuites() {
        return factory.getSupportedCipherSuites();
    }

    public String[] getSupportedCipherSuites() {
        return factory.getSupportedCipherSuites();
    }

 protected KeyManager[] getKeyManagers()
        throws IOException, GeneralSecurityException
      {
        // First, get the default KeyManagerFactory.
        String alg=KeyManagerFactory.getDefaultAlgorithm();
        KeyManagerFactory kmFact=KeyManagerFactory.getInstance(alg);

        // Next, set up the KeyStore to use. We need to load the file into
        // a KeyStore instance.

        ClassLoader cl = CustomSSLSocketFactory.class.getClassLoader();
        // read the file someTrustStore from the jar file from a classpath
        InputStream in = cl.getResourceAsStream("ssl/someTruststore.jks");
        //FileInputStream fis=new FileInputStream(adentTruststore.jks);
        KeyStore ks=KeyStore.getInstance("jks");
        ks.load(in, null);
        in.close();

        // Now we initialise the KeyManagerFactory with this KeyStore
        kmFact.init(ks, null);

        // And now get the KeyManagers
        KeyManager[] kms=kmFact.getKeyManagers();
        return kms;
      }
}

package util;
import java.security.cert.X509Certificate;

import javax.net.ssl.X509TrustManager;

public class CustomTrustManager implements X509TrustManager {

    public void checkClientTrusted(X509Certificate[] cert, String authType) {
        return;
    }

    public void checkServerTrusted(X509Certificate[] cert, String authType) {
        return;
    }

    public X509Certificate[] getAcceptedIssuers() {
        return new X509Certificate[0];
    }
}

لاز نقدر صبرك ، في محاولة للتعلم عندما أحصل على بعض الوقت. لقد بدأت في كتابة CustomSsLSOCKETFACTORY..RIGHT الآن أتجاوز الأمان ... استنادًا إلى مثال Solutions Platinum. إذا فعلت ذلك ... هل ستمر المعلومات كنص واضح على الشبكة؟

الآن أتساءل ما الذي يجب أن أفعله مع ملف TrustStore الذي أواجهه ملف "SometRustStore.jks". ماذا علي أن أفعل مع ذلك .. هل لديّ برامج TrustManager المخصصة الخاصة بي؟ من فضلك أرشدني في الاتجاه الصحيح.

-بادور

هل كانت مفيدة؟

المحلول

يمكنك القيام بذلك دون الحاجة إلى الاعتماد على خصائص النظام ونظام الملفات. إن قراءة keystore كدفق كما تفعل وإنشاء SSLSocketFactory الخاص بك سيكون أكثر نظافة.

import java.net.URL;
import java.security.KeyStore;
import java.security.SecureRandom;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;

...

    // assume keyStore is the KeyStore you read via getResourceAsStream
    final TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("SunX509");
    trustManagerFactory.init(keyStore);

    final SSLContext context = SSLContext.getInstance("SSL");
    context.init(null, trustManagerFactory.getTrustManagers(), new SecureRandom());

    final URL url = new URL("https://whatever");
    final HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();
    urlConnection.setSSLSocketFactory(context.getSocketFactory());

...

لم أتحقق ولكن لا أرى أي سبب لعدم العمل من خلال WebStart.

محدث:

أذكر أنك تتطلع إلى الاتصال بـ Active Directory ، لذا أعتقد أنك ستستخدم LDAPs كبروتوكول؟ إذا كان الأمر كذلك ، ربما الرمز في هذا عنوان URL يمكن أن تكون بمثابة مصدر إلهام؟ سيكون عليك إنشاء فئة فرعية من javax.net.ssl.SSLSocketFactory (يرى BlindSSLSocketFactoryTest في هذا الرابط PlatinumSolutions) الذي يلف المنطق أعلاه إنشاء SSLContext والمندوبين يدعو إلى SSLSocketFactory الذي - التي context.getSocketFactory() يخلق.

public class TrustedSSLSocketFactory extends SSLSocketFactory {
    private static SSLContext context;
    public static void initTrustedSSLSocketFactory(final KeyStore keyStore) throws Exception {
        final TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("SunX509");
        trustManagerFactory.init(keyStore);

        final SSLContext context = SSLContext.getInstance("SSL");
        context.init(null, trustManagerFactory.getTrustManagers(), new SecureRandom());
    }

    public static SocketFactory getDefault() {
        return context.getSocketFactory();
    }

    public Socket createSocket(String arg0, int arg1) throws IOException, UnknownHostException {
        return trustedFactory.createSocket(arg0, arg1);
    }

    public Socket createSocket(InetAddress arg0, int arg1) throws IOException {
        return trustedFactory.createSocket(arg0, arg1);
    }

    public Socket createSocket(String arg0, int arg1, InetAddress arg2, int arg3) throws IOException, UnknownHostException {
        return trustedFactory.createSocket(arg0, arg1, arg2, arg3);
    }

    public Socket createSocket(InetAddress arg0, int arg1, InetAddress arg2, int arg3) throws IOException {
        return trustedFactory.createSocket(arg0, arg1, arg2, arg3);
    }
}

آمل أن يجمع ذلك ، فأنا غير قادر على اختباره في الوقت الحالي! لاحظ أيضًا الكسل مع throws جملة على initTrustedSSLSocketFactory.

ثم عند إعداد بيئة LDAP ، استخدم

TrustedSSLSocketFactory.initTrustedSSLSocketFactory(keyStore);
env.put("java.naming.ldap.factory.socket", TrustedSSLSocketFactory.class.getName())

بطريقة مشابهة لرمز العينة في البلاتين. نأمل أن يكون هذا أكثر مما تبحث عنه؟

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top