JLDAP/TLS
程序员文章站
2022-07-12 22:47:37
...
import com.novell.ldap.LDAPJSSESecureSocketFactory;
import com.novell.ldap.LDAPConnection;
import com.novell.ldap.LDAPException;
import com.sun.net.ssl.SSLContext;
import com.sun.net.ssl.TrustManager;
import com.sun.net.ssl.X509TrustManager;
import com.sun.net.ssl.TrustManagerFactory;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileNotFoundException;
import java.security.Security;
import java.security.KeyStore;
import java.security.cert.X509Certificate;
import java.util.Enumeration;
import java.io.UnsupportedEncodingException;
public class TLSTrustManager
{
public static void main( String[] args )
{
try
{
// Check for valid arguments
if (args.length != 3 && args.length != 5)
{
System.err.println("Usage: java TLSTrustManager <host name>"
+ " <login dn> <password>"
+ " <keystore path> <keystore password>");
System.err.println("*Note: If <keystore path> does not"
+ " exist it will be created if the untrusted"
+ " certificate chain is trusted by the user."
);
System.err.println("Example: java TLSTrustManager Acme.com"
+ " \"cn=Admin,o=Acme\" secret my.keystore"
+ " mykeypass");
System.exit(1);
}
String ldapHost = args[0];
String loginDN = args[1];
String password = args[2];
String keyStorePath = args[3];
char[] keyStorePassword = args[4].toCharArray();
//dynamically set SunJSSE as a security provider
Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
// Open the keystore file.
FileInputStream keyStoreIStream = null;
try
{
// Open the stream to read in the keystore.
keyStoreIStream = new FileInputStream(keyStorePath);
}
catch( FileNotFoundException e )
{
// If the path does not exist then a null stream means
// the keystore is initialized empty. If an untrusted
// certificate chain is trusted by the user, then it will be
// saved in the file pointed to by keyStorePath.
keyStoreIStream = null;
}
// Create a KeyStore Object
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
// Init the Keystore with the contents of the keystore file.
// If the input stream is null the keystore is initialized empty.
keyStore.load(keyStoreIStream, keyStorePassword);
// Close keystore input stream
if(keyStoreIStream != null)
{
keyStoreIStream.close();
keyStoreIStream = null;
}
// Instantiate MyTrustManager that will handle server certificate
// chains.
TrustManager[] tms = {new MyTrustManager(keyStore,
keyStorePath,
keyStorePassword)};
// Create context based on a TLS protocol and a SunJSSE provider.
SSLContext context = SSLContext.getInstance("TLS", "SunJSSE");
// Initialize the SSL context with MyTrustManager.
// The first parameter - null means use the default key manager.
// The third parameter - null means use the default value
// "secure random".
context.init(null, tms, null);
// The socket factory must be set before the connection is made.
// Version 1.6 or later of the NDK must be used in order for this
// code to compile properly.
LDAPJSSESecureSocketFactory ssf =
new LDAPJSSESecureSocketFactory( context.getSocketFactory() );
// Create an LDAP connection object. Pass in the secure socket.
LDAPConnection lc = new LDAPConnection(ssf);
// Connect to the server.
lc.connect( ldapHost, LDAPConnection.DEFAULT_SSL_PORT );
// Authenticate to the server
lc.bind( LDAPConnection.LDAP_V3, loginDN, password.getBytes("UTF8") );
// At this point you are connected with a secure connection.
System.out.println( "Successful bind using TLS connection.");
// Close the connection.
lc.disconnect();
System.out.println( "Disconnect");
System.exit(0);
}
catch( UnsupportedEncodingException e ) {
System.out.println( "Error: " + e.toString() );
}
catch( LDAPException ex )
{
System.out.println( "LDAP Error: " + ex.toString() );
}
catch( Exception e )
{
System.out.println( "main Error: " + e.toString() );
System.exit(1);
}
}
// MyTrustManager
// This sub_class implements the X509TrustManager interface. MyTrustManager
// trusts known certificate chains, and queries the user to approve unknown
// chains. It will add trusted chains to the keystore.
private static class MyTrustManager implements X509TrustManager
{
private KeyStore keyStore;
private String keyStorePath;
private char[] keyStorePassword;
// MyTrustManager constructor. Save off keyStore object along with
// the path to the keystore (keyStorePath) and it's password
// (keyStorePassword).
public MyTrustManager(KeyStore keyStore,
String keyStorePath,
char[] keyStorePassword)
{
this.keyStore = keyStore;
this.keyStorePath = keyStorePath;
this.keyStorePassword = keyStorePassword;
}
// isClientTrusted checks to see if the chain is in the keyStore object.
// This is done with a call to isChainTrusted.
public boolean isClientTrusted(X509Certificate[] chain)
{
return isChainTrusted(chain);
}
// isServerTrusted checks to see if the chain is in the keyStore object.
// This is done with a call to isChainTrusted. If not it queries the
// user to see if the chain should be trusted and stored into the
// keyStore object. The keyStore is then saved in the file whose path
// keyStorePath
public boolean isServerTrusted(X509Certificate[] chain)
{
boolean trusted = false;
try
{
// See if the chain is in the keyStore object.
trusted = isChainTrusted(chain);
// If certificate is untrusted
if(!trusted)
{
System.out.println("Untrusted Certificate chain:");
for (int i = 0; i < chain.length; i++)
{
// display certificate chain information
System.out.println("Certificate chain[" + i + "]:");
System.out.println("Subject: "
+ chain[i].getSubjectDN().toString());
System.out.println("Issuer: "
+ chain[i].getIssuerDN().toString());
}
// Ask the user if the certificate should be trusted.
System.out.print("Trust this certificate chain and"
+ " add it to the keystore? (y or n) ");
int readStatus = System.in.read();
if(readStatus == 'y'|| readStatus == 'Y')
{
// Trust the chain.
trusted = true;
// Add Chain to the keyStore.
for (int i = 0; i < chain.length; i++)
{
keyStore.setCertificateEntry
(chain[i].getIssuerDN().toString(), chain[i]);
}
System.out.println("Certificate chain to keystore.");
// Save keystore to file.
FileOutputStream keyStoreOStream =
new FileOutputStream(keyStorePath);
keyStore.store(keyStoreOStream, keyStorePassword);
keyStoreOStream.close();
keyStoreOStream = null;
System.out.println("Keystore saved in " + keyStorePath);
}
else
trusted = false;
}
}
catch( Exception e )
{
System.out.println( "isServerTrusted Error: " + e.toString() );
trusted = false;
}
return trusted;
}
// getAcceptedIssuers retrieves all of the certificates in the keyStore
// and returns them in an X509Certificate array.
public X509Certificate[] getAcceptedIssuers()
{
X509Certificate[] X509Certs = null;
try
{
// See how many certificates are in the keystore.
int numberOfEntry = keyStore.size();
// If there are any certificates in the keystore.
if(numberOfEntry > 0)
{
// Create an array of X509Certificates
X509Certs = new X509Certificate[numberOfEntry];
// Get all of the certificate alias out of the keystore.
Enumeration aliases = keyStore.aliases();
// Retrieve all of the certificates out of the keystore
// via the alias name.
int i = 0;
while (aliases.hasMoreElements())
{
X509Certs[i] =
(X509Certificate)keyStore.
getCertificate((String)aliases.nextElement());
i++;
}
}
}
catch( Exception e )
{
System.out.println( "getAcceptedIssuers Exception: "
+ e.toString() );
X509Certs = null;
}
return X509Certs;
}
// isChainTrusted searches the keyStore for any certificate in the
// certificate chain.
private boolean isChainTrusted(X509Certificate[] chain)
{
boolean trusted = false;
try
{
// Start with the root and see if it is in the Keystore.
// The root is at the end of the chain.
for (int i = chain.length - 1; i >= 0; i-- )
{
if (keyStore.getCertificateAlias(chain[i]) != null)
{
trusted = true;
break;
}
}
}
catch( Exception e )
{
System.out.println( "isChainTrusted Exception: "
+ e.toString() );
trusted = false;
}
return trusted;
}
}
}
上一篇: HTTPs TLS1.2 请求模拟测试