Java Webstart 信任库 SSL

标签 java ssl java-web-start truststore

需要一些指导。

我有 java webstart 应用程序,我希望它通过 SSL 连接到服务器。只需添加一个属性,如:System.setProperty("javax.net.ssl.trustStore","my.keystore");但是自从从服务器下载的 JAWS 程序无法运行,并且在本地文件系统上没有 my.keystore。因此决定将证书分发给所有客户。我做了以下操作并且成功了。

  1. 将此信任库作为流读取(使用 getResourceAsStream 方法)。
  2. 将其保存在客户端机器上的任何文件中(sometemp)
  3. 调用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;
      }

-帕杜尔 ===========================**=============

/**

* */

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 感谢您的耐心等待,我会在有空的时候努力学习。 我开始编写自己的 CustomSSLSocketFactory..现在我正在绕过安全性...基于白金解决方案的示例。如果我这样做...信息会以明文形式在网络上传递吗?

现在我想知道我应该如何处理我拥有“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 工作。

更新:

您提到您希望连接到 Activity 目录,所以我猜您将使用 LDAPS 作为协议(protocol)?如果是这样,可能是 this URL 处的代码可以作为灵感吗?您必须创建 javax.net.ssl.SSLSocketFactory 的子类(请参阅该 platinumsolutions 链接上的 BlindSSLSocketFactoryTest),它包装了上面创建 SSLContext 的逻辑,并将调用委托(delegate)给 context 的 SSLSocketFactory .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);
    }
}

希望可以编译,我现在无法测试它!另请注意 initTrustedSSLSocketFactory 上的 throws 子句的惰性。

然后在设置 LDAP 环境时,使用

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

以类似于 platinumsolutions 的示例代码的方式。希望这是您正在寻找的更多内容?

关于Java Webstart 信任库 SSL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2804826/

相关文章:

python - SSL 错误不安全旧版重新协商已禁用

url - 什么改变了请求的 URL?

java - 在 JNLP 中加载 bcprov-jdk15on-1.50.jar 时出现问题

java - 以复杂数据类型作为输入的 Web 服务

java - Pdfbox 签名和保护,无需保存在文件系统中

Java 日历 - 设置 day_of_week 后日期不可预测

java - 在 2d 数组 Java 中存储 ArrayList

php - 子文件夹中的 wordpress htaccess 未重定向到 https

java - 使用 Java Web Start 远程部署项目

java - 如何在SpringSource Tool Suite中创建Roo Shell项目?