CXF RESTful Client - ssl

I have a rest org.apache.cxf.jaxrs.client.WebClient client for testing:
WebClient client = WebClient.create(URL);
and I want to make https request with cxf jax-rs
How can I do it? Examples?

ok, this is my solution:
public static void configureSSLOnTheClient(WebClient client,
String keyStoreFileName, String keyStorePassword,
String trustStoreFileName, String trustStorePassword) {
HTTPConduit httpConduit = (HTTPConduit) WebClient.getConfig(client).getConduit();
try {
TLSClientParameters tlsParams = new TLSClientParameters();
KeyStore keyStore;
KeyStore trustStore;
try {
keyStore = KeyStore.getInstance("JKS");
keyStore.load(ClassLoader.getSystemResourceAsStream(keyStoreFileName), keyStorePassword.toCharArray());
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(keyStore, keyStorePassword.toCharArray());
trustStore = KeyStore.getInstance("JKS");
trustStore.load(ClassLoader.getSystemResourceAsStream(trustStoreFileName), trustStorePassword.toCharArray());
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(trustStore);
SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), new SecureRandom());
tlsParams.setSSLSocketFactory(sslContext.getSocketFactory());
} catch (KeyStoreException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (CertificateException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
// These filters ensure that a ciphersuite with export-suitable or null encryption is used,
// but exclude anonymous Diffie-Hellman key change as this is vulnerable to man-in-the-middle attacks
FiltersType filters = new FiltersType();
filters.getInclude().add(".*_EXPORT_.*");
filters.getInclude().add(".*_EXPORT1024_.*");
filters.getInclude().add(".*_WITH_DES_.*");
filters.getInclude().add(".*_WITH_AES_.*");
filters.getInclude().add(".*_WITH_NULL_.*");
filters.getExclude().add(".*_DH_anon_.*");
tlsParams.setCipherSuitesFilter(filters);
httpConduit.setTlsClientParameters(tlsParams);
} catch (Exception exception) {
LOGGER.error("Security configuration failed with the following: " + exception.getCause(), exception);
}
}

Related

rest-assured with pfx file always returns 401

From this source: RESTAssured - use .pfx certificate for https call
I created below.
#Test
void testPfxKey() {
// Source: https://stackoverflow.com/questions/42235588/restassured-use-pfx-certificate-for-https-call
FileInputStream instream1=null;
KeyStore keyStore=null;
org.apache.http.conn.ssl.SSLSocketFactory lSchemeSocketFactory=null;
try {
instream1 = new FileInputStream(new File("C:/Path/To/pfxfile.pfx"));
keyStore = KeyStore.getInstance("PKCS12");
keyStore.load(instream1, "pfxfilepwd".toCharArray());
X509HostnameVerifier hostnameVerifier = org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER;
lSchemeSocketFactory = new org.apache.http.conn.ssl.SSLSocketFactory(keyStore, "pfxfilepwd");
lSchemeSocketFactory.setHostnameVerifier(hostnameVerifier);
} catch (Exception e) {
e.printStackTrace();
}
RestAssured.config = RestAssured.config().sslConfig(new SSLConfig().with().sslSocketFactory(lSchemeSocketFactory).and().allowAllHostnames().relaxedHTTPSValidation());
RestAssured.given().
contentType("application/json").
headers(
"Subscription-Key", "key-value",
"Accept-Encoding", "gzip,deflate"
);
Response response = RestAssured.get("https://endpoint.net/resource/path");
System.out.println(response.getStatusCode());
}
response.getStatusCode() always returns 401. I am expecting a 200. I have checked keyfile path, password and also the enpoint. All seem to be OK. When I run use ReadyAPI then I get a response. Please advice how to resolve this issue. Thanks you all!
I found this issue! I need to send headers with each request. Also .relaxedHTTPSValidation() should NOT be used in this case. We are in fact providing certificates that should be authenticated! Below code works:
#Test
void testPfxKey() {
FileInputStream instream1 = null;
KeyStore keyStore = null;
org.apache.http.conn.ssl.SSLSocketFactory lSchemeSocketFactory = null;
try {
instream1 = new FileInputStream(new File("C:/Path/To/pfxfile.pfx"));
keyStore = KeyStore.getInstance("PKCS12");
keyStore.load(instream1, "pfxfilepwd".toCharArray());
X509HostnameVerifier hostnameVerifier = org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER;
lSchemeSocketFactory = new org.apache.http.conn.ssl.SSLSocketFactory(keyStore, "pfxfilepwd");
lSchemeSocketFactory.setHostnameVerifier(hostnameVerifier);
} catch (Exception e) {
e.printStackTrace();
}
RestAssured.config = RestAssured.config().sslConfig(new SSLConfig().with().sslSocketFactory(lSchemeSocketFactory).and().allowAllHostnames());
System.out.println(
RestAssured.given().
contentType("application/json").
headers(
"Subscription-Key", "key-value",
"Accept-Encoding", "gzip,deflate"
)
.get("https://endpoint.net/resource/path")
.getStatusCode()
);
}

Find the algorithm of SSL Symmetric Encryption

Is there a way we could find what is the algorithm used to encrypt HTTPS requests between server and client after SSL handshake. looking at the network calls, server certificate or browser settings etc.
Using java you can try this.
private void printSSLDetails(){
String https_url = "https://www.google.com/";
URL url;
try {
url = new URL(https_url);
HttpsURLConnection con = (HttpsURLConnection)url.openConnection();
//dumpl all cert info
if(con!=null){
try {
System.out.println("Response Code : " + con.getResponseCode());
System.out.println("Cipher Suite : " + con.getCipherSuite());
System.out.println("\n");
Certificate[] certs = con.getServerCertificates();
for(Certificate cert : certs){
System.out.println("Cert Type : " + cert.getType());
System.out.println("Cert Hash Code : " + cert.hashCode());
System.out.println("Cert Public Key Algorithm : "
+ cert.getPublicKey().getAlgorithm());
System.out.println("Cert Public Key Format : "
+ cert.getPublicKey().getFormat());
System.out.println("\n");
}
} catch (SSLPeerUnverifiedException e) {
e.printStackTrace();
} catch (IOException e){
e.printStackTrace();
}
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}

Outbound (!) SSL connection Wildfly

our Wildfly 8.1-Server needs to establish an outbound (!) LDAPS-connection to a server within the organization's network. This connection is only used to sync various application data.
Unfortunately, there's no documentation about Wildfly's outbound-only truststore. Every research I do just gives me results about enabling SSL for inbound connections.
How exactly can I add a certificate to Wildfly's truststore for outbound SSL connections? Is there any documentation about this? I'd be thankful for any help on this topic.
Found two possible solutions. First the one i would not use:
System.setProperty("javax.net.ssl.trustStore",path_to_your_cacerts_file);
The second one I'd prefer:
public class LDAPSSocketFactory extends SSLSocketFactory {
private SSLSocketFactory actualSocketFactory;
public LDAPSSocketFactory() {
InputStream certificateInputStream = this.getClass().getClassLoader().getResourceAsStream("yourcert.pfx");
try {
KeyStore pkcs12 = KeyStore.getInstance("pkcs12");
pkcs12.load(certificateInputStream, "".toCharArray());
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(pkcs12);
SSLContext ctx = SSLContext.getInstance("TLS");
ctx.init(null, tmf.getTrustManagers(), null);
actualSocketFactory = ctx.getSocketFactory();
} catch (KeyStoreException e) {
e.printStackTrace();
} catch (CertificateException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (KeyManagementException e) {
e.printStackTrace();
}
}
//Override methods by simply deligating them to the actualSocketFactory
}
And pass this as an JNDI param for ldap connections:
env.put("java.naming.ldap.factory.socket", "LDAPSSocketFactory");
Found all of this on StackOverflow, but I forgot where exactly, so I basically pasted their solution here.

javax.net.ssl.sslpeerunverifiedexception no peer certificate Error In lifelogApi

We are getting SSL peer unverified error while fetching the access token from Lifelog api. I am able to get the authcode, but when i am trying to get access token, it is giving me SSL peer error. It works fine with few device, but most of the device it is giving SSL error.
private void getAccessToken(final String authCode)
{
final String finalUrl = String.format("https://platform.lifelog.sonymobile.com/oauth/2/token?client_id=%s&client_secret=%s&code=%s",CLIENT_ID,CLIENT_SECRET,authCode);
Thread networkThread = new Thread(new Runnable() {
public void run() {
try {
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost(finalUrl);
// Add your data
ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(4);
nameValuePairs.add(new BasicNameValuePair("client_id", CLIENT_ID));
nameValuePairs.add(new BasicNameValuePair("client_secret", CLIENT_SECRET));
nameValuePairs.add(new BasicNameValuePair("grant_type", "authorization_code"));
nameValuePairs.add(new BasicNameValuePair("code", authCode));
AbstractHttpEntity ent=new UrlEncodedFormEntity(nameValuePairs, HTTP.UTF_8);
ent.setContentType("application/x-www-form-urlencoded; charset=UTF-8");
post.setEntity(ent);
// Execute HTTP Post Request
HttpResponse response =null;
try {
response = client.execute(post);
Log.d("Response:" , response.toString());
} catch (IOException e) {
e.printStackTrace();
}
String dataObject = response.toString();
JSONObject obj;
if(dataObject != null) {
obj = null;
try {
String json_string = EntityUtils.toString(response.getEntity());
// displayToast(json_string);
obj = new JSONObject(json_string);
SharedPreferences prefs =getSharedPreferences("Myprefs", Context.MODE_PRIVATE);
prefs.edit().putString("Access_token", obj.getString("access_token"));
// prefs.edit().putString(AUTH_REFRESH_TOKEN, obj.getString(AUTH_REFRESH_TOKEN));
} catch (JSONException e) {
e.printStackTrace();
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
}
}
});
networkThread.start(); }
The problem may be with your use of HttpClient. It looks like Google has removed support for this call in Android 6.0.
http://developer.android.com/about/versions/marshmallow/android-6.0-changes.html#behavior-apache-http-client
You should be able to use HttpsURLConnection instead of Httpclient to access the Lifelog Web Service.
I'm using google-oauth-client, I was able to use on Android 5.x with this initialization for
import com.google.api.client.http.HttpTransport;
private void initializeSocketFactory() {
if (Build.VERSION.SDK_INT >= 23) {
HTTP_TRANSPORT = new NetHttpTransport();
} else {
//Android 5 and bellow needs this SSL Socket factory initialization
try {
SSLContext sslContext = SSLContext.getInstance("TLSv1");
sslContext.init(null, null, null);
SSLSocketFactory socketFactory = sslContext.getSocketFactory();
NetHttpTransport.Builder netTransportBuilder = new NetHttpTransport.Builder();
netTransportBuilder.setSslSocketFactory(socketFactory);
HTTP_TRANSPORT = netTransportBuilder.build();
} catch (NoSuchAlgorithmException | KeyManagementException e) {
Log.e(LOG_TAG, "Problem instantiating cipher for ssl socket", e);
}
}
}
You use HTTP_TRANSPORT to instantiate:
import com.google.api.client.auth.oauth2.AuthorizationCodeFlow;

Error obtaining i5 Keymanager and Trustmanager

Im trying to use send to paypal.
Im getting an error stating that my trustmanager has not been initialized. (I think).
This is my first steps into SSL so I may not have this set up correctly. Im getting SSlConfigurationException.
public static SSLContext setupClientSSL(String certPath, String certPassword)
throws SSLConfigurationException {
SSLContext sslContext = null;
try {
KeyManagerFactory kmf =
KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
KeyStore ks = p12ToKeyStore(certPath, certPassword);
kmf.init(ks, certPassword.toCharArray());
//sslContext = getSSLContext(kmf.getKeyManagers());
sslContext = SSLContext.getInstance("SSL", "IBMJSSE2");
} catch (NoSuchAlgorithmException e) {
throw new SSLConfigurationException(e.getMessage(), e);
} catch (KeyStoreException e) {
throw new SSLConfigurationException(e.getMessage(), e);
} catch (UnrecoverableKeyException e) {
throw new SSLConfigurationException(e.getMessage(), e);
} catch (CertificateException e) {
throw new SSLConfigurationException(e.getMessage(), e);
} catch (NoSuchProviderException e) {
throw new SSLConfigurationException(e.getMessage(), e);
} catch (IOException e) {
throw new SSLConfigurationException(e.getMessage(), e);
}
return sslContext;
}
The Information Center has documentation for using the Java Secure Socket Extension including setup and example code.