i have added all the certs to cacerts. using these cacerts and jks got from MQ team i have created a SSLConnectionFactory. and passed it to the Mqconnectionfactory. I have added VM args:
-Dcom.ibm.mq.cfg.useIBMCipherMappings=false
-Djavax.net.debug=all
-Dcom.ibm.mq.cfg.preferTLS=true
and we have unlimited JCE policy, JDK 1.8 , IBM MQ all client 9.0.4.0
Sample Code
private SSLSocketFactory getSocketFactory() {
KeyStore ks;
SSLSocketFactory sslSocketFactory = null;
String keystoreFile = environment.getProperty("ibmmq.keystoreFile");
String truststoreFile = environment.getProperty("ibmmq.truststoreFile");
String keystorePassword = environment.getProperty("ibmmq.keystorePassword");
String trustStorePassword = environment.getProperty("ibmmq.trustStorePassword");
try {
ks = KeyStore.getInstance("JKS");
ks.load(new FileInputStream(keystoreFile), keystorePassword.toCharArray());
KeyStore trustStore = KeyStore.getInstance("JKS");
trustStore.load(new FileInputStream(truststoreFile), trustStorePassword.toCharArray());
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(trustStore);
keyManagerFactory.init(ks, keystorePassword.toCharArray());
SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), null);
sslSocketFactory = sslContext.getSocketFactory();
logger.info("Initialized ssl socket factory... " + sslSocketFactory.toString());
} catch (KeyStoreException e) {
logger.error("KeyStoreException on getSocketFactory due to {}", e);
} catch (NoSuchAlgorithmException e) {
logger.error("NoSuchAlgorithmException on getSocketFactory due to {}", e);
} catch (CertificateException e) {
logger.error("CertificateException on getSocketFactory due to {}", e);
} catch (FileNotFoundException e) {
logger.error("FileNotFoundException on getSocketFactory due to {}", e);
} catch (IOException e) {
logger.error("IOException on getSocketFactory due to {}", e);
} catch (UnrecoverableKeyException e) {
logger.error("UnrecoverableKeyException on getSocketFactory due to {}", e);
} catch (KeyManagementException e) {
logger.error("KeyManagementException on getSocketFactory due to {}", e);
}
return sslSocketFactory;
}
private MQQueueConnectionFactory mqQueueConnectionFactoryBill() {
MQQueueConnectionFactory mqQueueConnectionFactory = new MQQueueConnectionFactory();
try {
mqQueueConnectionFactory.setHostName(environment.getProperty("ibmmq.host"));
mqQueueConnectionFactory.setPort(environment.getProperty("ibmmq.port", Integer.class));
mqQueueConnectionFactory.setTransportType(WMQConstants.WMQ_CM_CLIENT);
mqQueueConnectionFactory.setCCSID(WMQConstants.CCSID_UTF8);
mqQueueConnectionFactory.setChannel(environment.getProperty("ibmmq.channel"));
mqQueueConnectionFactory.setQueueManager(environment.getProperty("ibmmq.queue-manager"));
mqQueueConnectionFactory.setSSLCipherSuite(environment.getProperty("ibmmq.cipher.suite"));
mqQueueConnectionFactory.setSSLSocketFactory(getSocketFactory());
mqQueueConnectionFactory.setSSLFipsRequired(false);
System.out.println("mqQueueConnectionFactory initialized..!!! ==> " + mqQueueConnectionFactory.toString());
//System.out.println("mqQueueConnectionFactory connection ..!!! ==> " + mqQueueConnectionFactory.createConnection());
//System.out.println("mqQueueConnectionFactory ..!!! ==> " + mqQueueConnectionFactory.getClientReconnectOptions());
} catch (Exception e) {
e.printStackTrace();
}
return mqQueueConnectionFactory;
}
#Bean
public CachingConnectionFactory cachingConnectionFactory() {
CachingConnectionFactory cachingConnectionFactory = new CachingConnectionFactory();
cachingConnectionFactory.setTargetConnectionFactory(userCredentialsConnectionFactoryAdapterBill());
cachingConnectionFactory.setSessionCacheSize(500);
cachingConnectionFactory.setCacheProducers(true);
cachingConnectionFactory.setReconnectOnException(true);
return cachingConnectionFactory;
}
private UserCredentialsConnectionFactoryAdapter userCredentialsConnectionFactoryAdapterBill() {
UserCredentialsConnectionFactoryAdapter userCredentialsConnectionFactoryAdapter = new UserCredentialsConnectionFactoryAdapter();
userCredentialsConnectionFactoryAdapter.setUsername(environment.getProperty("ibmmq.username"));
userCredentialsConnectionFactoryAdapter.setPassword(environment.getProperty("ibmmq.password"));
userCredentialsConnectionFactoryAdapter.setTargetConnectionFactory(mqQueueConnectionFactoryBill());
return userCredentialsConnectionFactoryAdapter;
}
#Bean
public SimpleMessageListenerContainer sampleQueueContainer(#Autowired MessageListener listener) {
SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
container.setConnectionFactory(cachingConnectionFactory());
container.setDestinationName(environment.getProperty("ibmmq.mq.name"));
container.setMessageListener(listener);
container.afterPropertiesSet();
container.start();
return container;
}
Error As Follows
Caused by: com.ibm.mq.jmqi.JmqiException: CC=2;RC=2009;AMQ9213: A communications error for 'TCP' occurred. [1=java.net.SocketException[Connection reset],4=TCP,5=sockInStream.read]
at com.ibm.mq.jmqi.remote.impl.RemoteTCPConnection.receive(RemoteTCPConnection.java:1717) ~[com.ibm.mq.allclient-9.0.4.0.jar:9.0.4.0 - p904-L171030.1]
at com.ibm.mq.jmqi.remote.impl.RemoteConnection.receiveTSH(RemoteConnection.java:3110) ~[com.ibm.mq.allclient-9.0.4.0.jar:9.0.4.0 - p904-L171030.1]
at org.springframework.jms.listener.AbstractJmsListeningContainer.start(AbstractJmsListeningContainer.java:270) ~[spring-jms-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at com.sample.sampleMQConfig.sampleQueueContainer(sampleMQConfig.java:84) ~[classes/:?]
at com.sample.sampleMQConfig$$EnhancerBySpringCGLIB$$701bd166.CGLIB$sampleQueueContainer$3(<generated>) ~[classes/:?]
at com.sample.sampleMQConfig$$EnhancerBySpringCGLIB$$701bd166$$FastClassBySpringCGLIB$$8ac69a00.invoke(<generated>) ~[classes/:?]
at com.sample.sampleMQConfig$$EnhancerBySpringCGLIB$$701bd166.sampleQueueContainer(<generated>) ~[classes/:?]
Caused by: java.net.SocketException: Connection reset
at com.ibm.mq.ese.jmqi.ESEJMQI.jmqiConnect(ESEJMQI.java:562) ~[com.ibm.mq.allclient-9.0.4.0.jar:9.0.4.0 - p904-L171030.1]
at com.ibm.msg.client.wmq.internal.WMQConnection.<init>(WMQConnection.java:357) ~[com.ibm.mq.allclient-9.0.4.0.jar:9.0.4.0 - p904-L171030.1]
at org.springframework.jms.listener.AbstractJmsListeningContainer.start(AbstractJmsListeningContainer.java:270) ~[spring-jms-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at com.sample.sampleMQConfig.sampleQueueContainer(sampleMQConfig.java:84) ~[classes/:?]
Related
I didn't find any way to implement an SSLContext with DownloadManager. Is there a way to add a Client certificate (keystore)?
For now, it is a self signed certificate (both client&server). I'm able to connect to this server with okhttp (managing SSLContext) but with DownloadManager i get an error 'SSL Handshake'.
Here is my code,
#Nullable
private static SSLContext initTrustManager(Context context) {
try {
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
InputStream is = context.getAssets().open("s_cert.cer");
Certificate ca;
try {
ca = certificateFactory.generateCertificate(is);
Log.i("TrustManager", "ca=" + ((X509Certificate) ca).getSubjectDN());
} finally {
is.close();
}
String keyStoreType = KeyStore.getDefaultType();
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(keyStore);
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, tmf.getTrustManagers(), null);
return sslContext;
} catch (CertificateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (KeyStoreException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyManagementException e) {
e.printStackTrace();
}
return null;
}
And here is how I implement it:
builder.sslSocketFactory(initTrustManager(context).getSocketFactory());
This is working code, so if you still get exceptions, pay attention to SSL certificate itself or make some changes inside api of server. Hope it helps))
I'm trying to connect to my API server using a self-signed certificate. The certificate was successfully installed on the server. I've tested it via OpenSSL and also in Firefox.
I followed the Andrey Makarov's answer to configure OkHttp. But it doesn't work. When I try to execute my request I get javax.net.ssl.SSLHandshakeException with java.security.cert.CertPathValidatorException: Trust anchor for certification path not found message.
Here is my code:
public HttpClient() {
/* ... */
SSLContext sslContext = null;
try {
sslContext = SSLContext.getInstance("TLSv1.2");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
KeyStore keyStore = readKeyStore();
TrustManagerFactory trustManagerFactory = null;
try {
trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(keyStore);
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(keyStore, "password".toCharArray());
sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), new SecureRandom());
}
catch (final Exception e) {
Log.e(TAG, e.toString());
}
TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
X509TrustManager trustManager = (X509TrustManager) trustManagers[0];
OkHttpClient client = new OkHttpClient.Builder()
.sslSocketFactory(sslContext.getSocketFactory(), trustManager)
.build();
mRetrofit = new Retrofit.Builder()
.client(client)
.baseUrl(mBaseUrl)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
private KeyStore readKeyStore() {
KeyStore ks = null;
try {
ks = KeyStore.getInstance("BKS");
}
catch (final Exception e) {
Log.e(TAG, e.toString());
}
char[] password = "password".toCharArray();
final Context context = App.app;
InputStream is = context.getResources().openRawResource(R.raw.key_sorage);
try {
ks.load(is, password);
}
catch (final Exception e) {
Log.e(TAG, e.toString());
}
finally {
if (is != null) {
try {
is.close();
}
catch (final Exception e2) {
Log.e(TAG, e2.toString());
}
}
}
return ks;
}
Retrofit version is 2.3.0.
I am unable to load keystore.
I want to add sslSocketFactory in OkHttpClient Retrofit
After Loading ".p12" File from inputstream into keystore.load method i am getting below exception
"Method threw 'java.io.IOException' exception. stream does not represent a pkcs12 key store retrofit android".
Method which returns SSLSocketFactory
public static SSLSocketFactory getSSLSocketFactory() {
SSLContext sslContext = null;
try {
String password = ""; // .p12 is without a password.
// Load CAs from an InputStream
InputStream caInput = MainApplication.context.getResources()
.openRawResource(R.raw.generic_client_cert); // file present in Row directory with "generic_client_cert.p12" name.
KeyStore keyStore = KeyStore.getInstance("PKCS12");
keyStore.load(caInput, password.toCharArray());
Exception at above line.
KeyManagerFactory kmf = KeyManagerFactory.getInstance("X509");
kmf.init(keyStore, password.toCharArray());
KeyManager[] keyManagers = kmf.getKeyManagers();
// creating an SSLSocketFactory that uses our TrustManager
sslContext = SSLContext.getInstance("TLS");
sslContext.init(keyManagers, null, null);
} catch (IOException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (CertificateException e) {
e.printStackTrace();
} catch (KeyStoreException e) {
e.printStackTrace();
} catch (KeyManagementException e) {
e.printStackTrace();
} catch (UnrecoverableKeyException e) {
e.printStackTrace();
}
return sslContext.getSocketFactory();
}
What went wrong? any help will be great (^_^)
Thanks
I have to connect to a server via SSL dual authentication. I have added my own private key plus certificate to a keystore.jks and the self signed certificate of the server to a truststore.jks, both files are copied to /usr/share/tomcat7. The socket factory used by my code is delivered by the following provider:
#Singleton
public static class SecureSSLSocketFactoryProvider implements Provider<SSLSocketFactory> {
private SSLSocketFactory sslSocketFactory;
public SecureSSLSocketFactoryProvider() throws RuntimeException {
try {
final KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
final InputStream trustStoreFile = new FileInputStream("/usr/share/tomcat7/truststore.jks");
trustStore.load(trustStoreFile, "changeit".toCharArray());
final TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(trustStore);
final KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
final InputStream keyStoreFile = new FileInputStream("/usr/share/tomcat7/keystore.jks");
keyStore.load(keyStoreFile, "changeit".toCharArray());
final KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(keyStore, "changeit".toCharArray());
final SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), null);
this.sslSocketFactory = sslContext.getSocketFactory();
} catch (final KeyStoreException e) {
Log.error("Key store exception: {}", e.getMessage(), e);
} catch (final CertificateException e) {
Log.error("Certificate exception: {}", e.getMessage(), e);
} catch (final UnrecoverableKeyException e) {
Log.error("Unrecoverable key exception: {}", e.getMessage(), e);
} catch (final NoSuchAlgorithmException e) {
Log.error("No such algorithm exception: {}", e.getMessage(), e);
} catch (final KeyManagementException e) {
Log.error("Key management exception: {}", e.getMessage(), e);
} catch (final IOException e) {
Log.error("IO exception: {}", e.getMessage(), e);
}
}
#Override
public SSLSocketFactory get() {
return sslSocketFactory;
}
}
When I try to connect to an endpoint on the server I get the following exception though:
javax.net.ssl.SSLHandshakeException: Received fatal alert: unknown_ca
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192) ~[na:1.7.0_45]
at sun.security.ssl.Alerts.getSSLException(Alerts.java:154) ~[na:1.7.0_45]
at sun.security.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:1959) ~[na:1.7.0_45]
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1077) ~[na:1.7.0_45]
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1312) ~[na:1.7.0_45]
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1339) ~[na:1.7.0_45]
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1323) ~[na:1.7.0_45]
at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:563) ~[na:1.7.0_45]
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185) ~[na:1.7.0_45]
at sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:153) ~[na:1.7.0_45]
Any idea what I have missed here?
If you get an alert unknown_ca back from the server, then the server did not like the certificate you've send as the client certificate, because it is not signed by a CA which is trusted by the server for client certificates.
Hi I am testing Android connecion with certificate.
I have created a default ssl server on my ubuntu desktop. Enabled ssl and created the default self-signed certificate. I have then connected to https://localhost with firefox, added certificate to exceptions and then I used Firefox to save cerificate as .pem file.
I added certificate.pem to my android projetc in res/raw
I have gotten this code from android developer website to connect via https using my certificate (I don't want to trust everything I just want to verify if certicate is correct using the certificate in raw folder).
So when I connect I get:
java.lang.RuntimeException: java.io.IOException: Hostname '192.168.1.111' was not verified
Here is the class I use to verify the certificate
public class VerifyKey extends AsyncTask<Void, Void, Void>{
public static final String CERTIFICATE_TYPE_X_509 = "X.509";
public static final String CERTIFICATE_ALIAS = "user_desktop";
public static final String SERVER_URL = "https://192.168.1.111";
#Override
protected Void doInBackground(Void... params) {
// Load CAs from an InputStream
// (could be from a resource or ByteArrayInputStream or ...)
CertificateFactory cf = null;
InputStream certificateInputStream = getApplicationContext().getResources().openRawResource(R.raw.user_desktop);
Certificate certificate = null;
try {
cf = CertificateFactory.getInstance(CERTIFICATE_TYPE_X_509);
certificate = cf.generateCertificate(certificateInputStream);
Log.d(TAG, "Certificate : " + certificate.toString());
Log.d(TAG, "Certificate public key : " + certificate.getPublicKey());
} catch (CertificateException e) {
throw new RuntimeException(e);
} finally {
if (certificateInputStream != null) {
try {
certificateInputStream.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
// Create a KeyStore containing our trusted CAs
String keyStoreType = KeyStore.getDefaultType();
KeyStore keyStore = null;
try {
keyStore = KeyStore.getInstance(keyStoreType);
if (keyStore != null) {
keyStore.load(null, null);
keyStore.setCertificateEntry(CERTIFICATE_ALIAS, certificate);
} else {
throw new RuntimeException("KeyStore is null");
}
} catch (KeyStoreException e) {
throw new RuntimeException(e);
} catch (CertificateException e) {
throw new RuntimeException(e);
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
// Create a TrustManager that trusts the CAs in our KeyStore
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = null;
try {
tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
if (tmf != null) {
tmf.init(keyStore);
} else {
throw new RuntimeException("TrustManagerFactory is null");
}
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
} catch (KeyStoreException e) {
throw new RuntimeException(e);
}
// Create an SSLContext that uses our TrustManager
SSLContext sslContext = null;
try {
sslContext = SSLContext.getInstance("TLS");
TrustManager[] trustManagers = tmf.getTrustManagers();
sslContext.init(null, trustManagers, null);
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
} catch (KeyManagementException e) {
throw new RuntimeException(e);
}
// Tell the URLConnection to use a SocketFactory from our SSLContext
URL url = null;
HttpsURLConnection httpsURLConnection =
null;
InputStream in = null;
try {
url = new URL(SERVER_URL);
Log.d(TAG, "URL : "+url.toString());
httpsURLConnection = (HttpsURLConnection)url.openConnection();
SSLSocketFactory socketFactory = sslContext.getSocketFactory();
Log.d(TAG, "Socket factory : "+socketFactory.toString());
httpsURLConnection.setSSLSocketFactory(socketFactory);
in = httpsURLConnection.getInputStream(); //IOException exception gets triggered here
Toast.makeText(getApplicationContext(), in.toString(), Toast.LENGTH_SHORT).show();
} catch (MalformedURLException e) {
throw new RuntimeException(e);
} catch (SSLHandshakeException e){
throw new RuntimeException(e);
} catch(UnknownHostException e){
throw new RuntimeException(e);
} catch (ConnectException e1){
throw new RuntimeException(e1);
} catch (IOException e) {
throw new RuntimeException(e);
}
return null;
}
}
I have gotten this code from http://developer.android.com/training/articles/security-ssl.html#SelfSigned
I get this error on Samsung Galaxy s4 with Android 4.3
I don't have a lot of experience with HTTPS so here what I would like to achieve is povide certificate with the app which will allow to verify the server certificate.
Please if someone can suggest what I can modify in the code.
I also have a doubt because my server is a .local server but I connect using ip and the objective is to be able to connect using both ip a hostname, will that be problem when veryfying the hostname?
Thanks a lot in advance
EDIT: I have added code to get the hostname:
InetAddress addr = InetAddress.getByName(SERVER_URL);
String hostName = addr.getHostName();
I have tried using the hostname instead of ip but still I get the same exception:
Caused by: java.io.IOException: Hostname '<user.hostname.com>' was not verified
at libcore.net.http.HttpConnection.verifySecureSocketHostname(HttpConnection.java:223)
at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.connect(HttpsURLConnectionImpl.java:446)
at libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:290)
at libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:240)
at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:282)
at libcore.net.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:177)
at libcore.net.http.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:271)
I have managed to solve the problem, it was actually a problem with the certificate:
sudo a2enmod ssl
sudo rm -rf /etc/apache2/ssl
sudo mkdir /etc/apache2/ssl
sudo openssl req -new -x509 -days 365 -nodes -out /etc/apache2/ssl/apache.pem -keyout /etc/apache2/ssl/apache.key
copy /etc/apache2/ssl/apache.pem somewhere else, change permissions of it to 777 (???)
and then add new apache.pem to res/raw folder of the app
then in common name field I have set the FQDN of my server such as host.name.com, I then updated the cerificate and key settings in /etc/apache2/sites-available/default-ssl
All this thanks to site https://library.linode.com/web-servers/apache/ssl-guides/ubuntu-10.04-lucid