简体   繁体   English

Java Webstart Truststore SSL

[英]Java Webstart Truststore SSL

Need some guidance. 需要一些指导。

I have java webstart app and I want it to connect to a server via SSL.just adding a property like:System.setProperty("javax.net.ssl.trustStore","my.keystore");But since a JAWS program is downloaded from server didn't work and don't have a my.keystore on local file system. 我有java webstart应用程序,我希望它通过SSL连接到服务器。只需添加一个属性,如:System.setProperty(“javax.net.ssl.trustStore”,“my.keystore”);但是因为JAWS程序是从服务器下载不起作用,本地文件系统上没有my.keystore。 So decided to distribute the certificate to all clients.I did the following and it worked. 所以决定将证书分发给所有客户。我做了以下工作。

  1. Read this trust store as a stream (use getResourceAsStream method). 将此信任存储读取为流(使用getResourceAsStream方法)。
  2. Save it in any file on the client machine (sometemp) 将其保存在客户端计算机上的任何文件中(sometemp)
  3. Call System.setProperty ("javax.net.ssl.trustStore", trustStorePath); 调用System.setProperty(“javax.net.ssl.trustStore”,trustStorePath);

But I am sure there must be better solutions than this.. Any ideas to make it better? 但我相信必须有比这更好的解决方案..任何想法让它变得更好?

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 ===========================**============= -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];
    }
}

Laz appreciate your patience, trying to learn when I get some time. Laz感谢您的耐心,在我有空的时候尝试学习。 I started writing my own CustomSSLSocketFactory..right now I am bypassing security...based on the example by platinum solutions.If I do that ...will the information pass as a clear text on the network? 我开始编写我自己的CustomSSLSocketFactory..right现在我绕过了安全性...基于铂金解决方案的例子。如果我这样做...信息会在网络上作为明文传递吗?

Now I wonder what should I do with the truststore file I am having "sometruststore.jks" file. 现在我想知道我应该怎么处理信任库文件我有“sometruststore.jks”文件。 What should I do with that ..Do I have wrie my own custom trustmanager software ? 我应该怎么做..我是否有自己的自定义信任管理软件? Please guide me in correct direction. 请指导我正确的方向。

-padur -padur

You could do it without having to rely on system properties and the file system. 您可以在不必依赖系统属性和文件系统的情况下完成此操作。 Reading the keystore as a stream like you are doing and creating your own SSLSocketFactory would be much cleaner. 像你正在做的那样读取密钥库并创建自己的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());

...

I haven't verified but I see no reason why this shouldn't work through Webstart. 我没有验证,但我认为没有理由为什么这不应该通过Webstart工作。

Updated: 更新:

You mention that you are looking to connect to active directory so I'm guessing you are going to use LDAPS as the protocol? 你提到你正在寻找连接到活动目录所以我猜你将使用LDAPS作为协议? If so, maybe the code at this URL can serve as inspiration? 如果是这样,也许这个URL的代码可以作为灵感? You'll have to create a subclass of javax.net.ssl.SSLSocketFactory (see BlindSSLSocketFactoryTest at that platinumsolutions link) that wraps the logic above of creating the the SSLContext and delegates calls to the SSLSocketFactory that context.getSocketFactory() creates. 您必须创建javax.net.ssl.SSLSocketFactory的子类(请参阅该platinumsolutions链接中的BlindSSLSocketFactoryTest ),该子类包含创建SSLContext上述逻辑,并将调用委托给context.getSocketFactory()创建的SSLSocketFactory

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

Hopefully that compiles, I'm unable to test it at the moment! 希望编译,我现在无法测试它! Also note the laziness with the throws clause on initTrustedSSLSocketFactory . 还要注意initTrustedSSLSocketFactory上的throws子句的懒惰。

Then when you setup the LDAP environment, use 然后,在设置LDAP环境时,请使用

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

in a similar manner to the sample code at platinumsolutions. 以类似于platinumsolutions的示例代码的方式。 Hopefully this is more of what you're looking for? 希望这更像是你在寻找什么?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM