我对密钥库、信任库和Google的LDAP凭据有问题。
我在JDK17上使用JDK17 22.2进行测试。
我创建了一个测试类,以便能够登录到Google。一旦我知道如何在测试中完成它,我就可以将它移到我们的应用程序中。
我下载了我的Google证书和密钥。然后,我按照Google的指示创建了一个KeyStore:https://support.google.com/a/answer/9089736?hl=en#other-java-applications
根据Google的说明,您只需在系统属性中添加以下内容:
-Djavax.net.ssl.keyStore=File路径到KeyStore -Djavax.net.ssl.keyStorePassword=KeyStore Pass
-或者
System.setProperty("javax.net.ssl.keyStorePassword",System.setProperty("javax.net.ssl.keyStore",“文件路径到KeyStore");
这方面的问题是,我们将有一个KeyStore,其密码与特定的LDAP服务器相对应。这是因为我们的应用程序能够连接到多个LDAP服务器。
在做了一些研究之后,我看到您可以创建一个"java.naming.ldap.factory.socket".并设置属性SSLSocketFactory。在那里,您可以通过TrustManager或KeyManager添加要使用的TrustManager。
我的问题是,当试图连接到Google服务器时,SSLSocketFactory被完全忽略了。我怎么知道?没有输出SSLSocketFactory、TrustManger或KeyManager中的调试语句。(我为调试目的添加了一个KeyStoreManager。)
我甚至试图在没有运气的情况下将keystore导入仙人掌。事实上,我在导入时遇到了多个问题,因为"keytool“一直在抱怨JKS PKCS12格式。
唯一能成功连接的方法是添加两个系统属性。我知道我错过了一些简单的东西,可以解释为什么它不能正常工作。有人有什么想法吗?
这是我的考试课:
import java.io.Console;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.security.KeyStore;
import java.security.Principal;
import java.security.PrivateKey;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Properties;
import javax.naming.Context;
import javax.naming.directory.InitialDirContext;
import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509KeyManager;
import javax.net.ssl.X509TrustManager;
public class LDAPIT {
public static final String JAVA_NAMING_LDAP_FACTORY_SOCKET = "java.naming.ldap.factory.socket";
public static void main(final String[] args) {
final LDAPIT test = new LDAPIT();
try {
test.run();
} catch (final Exception e) {
throw new RuntimeException(e);
}
}
public void run() throws Exception {
final Console cnsl = System.console();
if (cnsl == null) {
throw new RuntimeException("Console is null");
}
final String url = cnsl.readLine("Enter URL: ");
final String user = cnsl.readLine("Enter username : ");
final String password = String.valueOf(cnsl.readPassword("Enter password : "));
System.out.println("Start Trying to Connect to LDAP: " + url);
System.out.println("With User: " + user);
System.out.println("Creating LDAP Properties");
final Properties props = new Properties();
props.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
props.put(Context.PROVIDER_URL, url);
props.put(Context.SECURITY_PRINCIPAL, user);
props.put(Context.SECURITY_AUTHENTICATION, "simple");
props.put(Context.SECURITY_PROTOCOL, "ssl");
props.put(JAVA_NAMING_LDAP_FACTORY_SOCKET, MySSLSocketFactory.class.getName());
System.out.println("LDAP Properties without password: " + props);
props.put(Context.SECURITY_CREDENTIALS, password);
// System.setProperty("javax.net.ssl.keyStore", "[File Path to KeyStore]");
// System.setProperty("javax.net.ssl.keyStorePassword", "[KeyStore Pass]");
try {
System.out.println("Connecting to LDAP Server");
final InitialDirContext idc = new InitialDirContext(props);
System.out.println("Successfully connected to LDAP");
idc.close();
} catch (final Exception e) {
e.printStackTrace();
}
System.out.println("End Trying to Connect to LDAP");
}
public static class MySSLSocketFactory extends SSLSocketFactory {
private SSLSocketFactory socketFactory;
public MySSLSocketFactory() {
try {
System.out.println("Creating Key Manager");
final MyKeyManager keyManager = new MyKeyManager();
final KeyManager[] keyManagers = {keyManager};
System.out.println("Creating Trust Manager");
final MyTrustManager trustManager = new MyTrustManager();
final TrustManager[] trustManagers = {trustManager};
System.out.println("Creating Socket Context");
final SSLContext ctx = SSLContext.getInstance("TLS");
System.out.println("Initializing Socket Context");
ctx.init(keyManagers, trustManagers, new SecureRandom());
System.out.println("Creating Socket Factory");
socketFactory = ctx.getSocketFactory();
} catch (final Exception ex) {
ex.printStackTrace();
}
}
@Override
public String[] getDefaultCipherSuites() {
return socketFactory.getDefaultCipherSuites();
}
@Override
public String[] getSupportedCipherSuites() {
return socketFactory.getSupportedCipherSuites();
}
@Override
public Socket createSocket(Socket socket, String string, int i, boolean bln) throws IOException {
System.out.println("Creating Socket with: Socket, String, int, Boolean");
return socketFactory.createSocket(socket, string, i, bln);
}
@Override
public Socket createSocket(final Socket s, final InputStream consumed, final boolean autoClose) throws IOException {
System.out.println("Creating Socket with: Socket, InputStream, Boolean");
return super.createSocket(s, consumed, autoClose);
}
@Override
public Socket createSocket() throws IOException {
System.out.println("Creating Socket without parameters");
return super.createSocket();
}
@Override
public Socket createSocket(String string, int i) throws IOException {
System.out.println("Creating Socket with: String ,int");
return socketFactory.createSocket(string, i);
}
@Override
public Socket createSocket(String string, int i, InetAddress ia, int i1) throws IOException {
System.out.println("Creating Socket with: String, int, InetAddress, int");
return socketFactory.createSocket(string, i, ia, i1);
}
@Override
public Socket createSocket(InetAddress ia, int i) throws IOException {
System.out.println("Creating Socket with: InetAddress, int");
return socketFactory.createSocket(ia, i);
}
@Override
public Socket createSocket(InetAddress ia, int i, InetAddress ia1, int i1) throws IOException {
System.out.println("Creating Socket with: InetAddress, InetAddress, int");
return socketFactory.createSocket(ia, i, ia1, i1);
}
}
public static class MyKeyManager implements X509KeyManager {
@Override
public String[] getClientAliases(final String keyType, final Principal[] issuers) {
System.out.println("Getting Client Aliases: String, Principal[]");
return new String[0];
}
@Override
public String chooseClientAlias(final String[] keyType, final Principal[] issuers, final Socket socket) {
System.out.println("Choosing Client Alias: String[], Principal[], Socket");
return null;
}
@Override
public String[] getServerAliases(final String keyType, final Principal[] issuers) {
System.out.println("Getting Server Aliases: String, Principal[]");
return new String[0];
}
@Override
public String chooseServerAlias(final String keyType, final Principal[] issuers, final Socket socket) {
System.out.println("Choosing Server Aliases: String, Principal[], Socket");
return null;
}
@Override
public X509Certificate[] getCertificateChain(final String alias) {
System.out.println("Getting Certificate Chain: String");
return new X509Certificate[0];
}
@Override
public PrivateKey getPrivateKey(final String alias) {
System.out.println("Getting Private Key: String");
return null;
}
}
public static class MyTrustManager implements X509TrustManager {
private X509TrustManager gTrustManager;
public MyTrustManager() {
System.out.println("Creating My Trust Manager");
initTrustManager();
System.out.println("Created My Trust Manager");
}
@Override
public void checkClientTrusted(final X509Certificate[] chain, final String authType) throws CertificateException {
if (gTrustManager != null) {
gTrustManager.checkClientTrusted(chain, authType);
}
}
@Override
public void checkServerTrusted(final X509Certificate[] chain, final String authType) throws CertificateException {
if (gTrustManager != null) {
gTrustManager.checkServerTrusted(chain, authType);
}
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return gTrustManager.getAcceptedIssuers();
}
private void initTrustManager() {
try {
final String keystoreType = KeyStore.getDefaultType();
System.out.println("Loading Keystore Type: " + keystoreType);
KeyStore keyStore = KeyStore.getInstance(keystoreType);
System.out.println("Loading CA Certs");
loadCACerts(keyStore);
System.out.println("Creating SSL Context");
System.out.println("Creating Trust Manager");
gTrustManager = getTrustManager(keyStore);
} catch (final Exception e) {
e.printStackTrace();
}
}
private void loadCACerts(final KeyStore keyStore) throws Exception {
final File keyStoreFile = new File("[File Path to KeyStore]]");
System.out.println("Loading Keystore: " + keyStoreFile.getAbsolutePath());
try (final FileInputStream keyStoreInputStream = new FileInputStream(keyStoreFile)) {
keyStore.load(keyStoreInputStream, "[KeyStore Pass]".toCharArray());
}
System.out.println("Keystore Loaded");
}
private X509TrustManager getTrustManager(final KeyStore k) throws Exception {
final String defaultAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
System.out.println("Loading Trust Manager Algorithm: " + defaultAlgorithm);
final TrustManagerFactory tmf = TrustManagerFactory.getInstance(defaultAlgorithm);
System.out.println("Initializing Trust Manager Factory");
tmf.init(k);
System.out.println("Getting Trust Managers");
final TrustManager[] tms = tmf.getTrustManagers();
int arraySize = 0;
if (tms != null) {
arraySize = tms.length;
}
System.out.println("Iterating through Trust Managers: " + arraySize);
for (final TrustManager tm : tms) {
System.out.println("Trust Manager: " + tm.getClass().getName());
if (tm instanceof final X509TrustManager x509TrustManager) {
System.out.println("Returning X509TrustManager");
return x509TrustManager;
}
}
System.out.println("Could not find correct Trust Manager, returning Null");
return null;
}
}
}发布于 2022-10-24 21:45:27
你难道不知道吗,it...after,我问的问题,我搞清楚了。答案是您必须在自定义的getDefault()方法中实现'getDefault()‘方法。我就知道这很简单。
https://docs.oracle.com/javase/jndi/tutorial/ldap/security/ssl.html
查看使用自定义套接字的。
https://stackoverflow.com/questions/74186950
复制相似问题