Java Webstart信任库SSL
-
25-09-2019 - |
题
需要一些指导。
我java webstart程序,我希望它连接到一个服务器通过SSL。只是增加的一个属性,如:系统。setProperty("内网。ssl。任库","我的.钥库");但是,由于一个爪程序被下载服务器没有工作和没有我的。密钥对当地文件系统。所以决定分发该证书给所有客户。我做了下列和它的工作。
- 阅读此信任储存作为一个流(使用getResourceAsStream方法)。
- 它保存在任何文件上的客户机(sometemp)
- 呼叫系统。setProperty("内网。ssl。任库",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..现在我绕过安全...基于例如通过白金解决方案。如果我这样做...将信息传递一个明确的文字网络上的?
现在我不知道我应该怎么做信任库文件,我有"sometruststore.险,改善现金状况来提高"的文件。我应该怎么做,那..我有写我自己的定义trustmanager的软件吗?请指引我在正确的方向。
-padur
解决方案
你可以做到这一点,而无需依赖系统的特性和文件的系统。阅读该密钥作为一个流像你们这样做,创造你自己的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。
更新:
你说你正在寻找连接以主动目录所以我猜你要使用LDAPS作协议?如果是这样,也许可代码 这个网址 可以作为灵感的?你就必须创建一个亚类的 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())
在一个类似的方式样的代码,在platinumsolutions.希望这个是你在找什么?