Android: Authenicating with certificates for Exchange Server using HTTP Methods - android

I am trying to sync with my exchange server using HTTP Methods(HttpPost) with the client certificate (abc.pfx) which is generated by the server. I tried using KeyStore, KeyManagerFactory,TrustManagerFactory and SSLSocketFactory to acheive this. But iam getting
Authentication Error (If i trust all certificates) Received authentication challenge is null
java.security.cert.CertificateException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found. (If i trust only the server (Root CA) cert).
I had gone through many Links in StackOverflow 1,2,3,4. If u can see all the links are atmost same. I tried different ways but still no use.
Note: I am using abc.pfx (it is not self signed), server.cer (to make this trust). Iam converting both file into BKS format and using in my code. Plz help me to solve this problem

Related

Enabling HTTPS communication between my server and my client

I have already built a server app and an android app. So far they were communicating over http, but I am sending sensitive information in each request (like JWT). Therefore I neet to use Https instead.
I have generated a p12 certificate.
On the server side:
I've copied the certificate to resources/keystore/sampleName.p12
I've added these lines to my application.properties
server.ssl.key-store-type=PKCS12
server.ssl.key-store-password=samplePassword
server.ssl.key-store=classpath:keystore/sampleName.p12
server.ssl.key-alias=sampleName
On android side I use okHttp and create the client like this
val httpClient = OkHttpClient.Builder()
.certificatePinner(
CertificatePinner.Builder()
.add(
https://10.0.2.2:8080,
"sha256/lVIcG+gpmlabsq1bW5RbvB+kqVSHKdOFyoxjo9+SLEs="
).build()
)
.build()
I use https://10.0.2.2:8080 because I run the server app only localy and I also run the android app on an emulator on the same laptop.
To get sha256/lVIcG+gpmlabsq1bW5RbvB+kqVSHKdOFyoxjo9+SLEs= I've used keytool -list -v -keystore sampleName.p12 -storetype PKCS12 -storepass samplePassword and converted the sha256 fingerprint which was in hex to base64.
Now when I try to send any request to the server I get an
javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found
I am clearly missing something but I dont know what. Is there anything else I need to do? Or did I do something wrong? Or is it just not supposed to work localy?
Note that this is just an exercise for me and I won't be actually deploying the server app on any real server and I won't release the android app.
But still I will be presenting the solution and I really nedd it to be solid and work localy.
CertificatePinning is in addition to the normal certificate checks. It only further restricts the choice of certificate, since be default you will accept any cert for your host.
See Adding a custom certificate to an OkHttp Client for an existing answer.
Or read up here
https://github.com/square/okhttp/blob/master/samples/guide/src/main/java/okhttp3/recipes/CustomTrust.java
https://square.github.io/okhttp/4.x/okhttp/okhttp3/-certificate-pinner/

com.android.volley.NoConnectionError: javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException

i need to get echo value i.e (yes or no) from php file to myresulttextview but unable to retrieve it says error :"com.android.volley.NoConnectionError: javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found. "
val barcode = data.getParcelableExtra<Barcode>(BarcodeCaptureActivity.BarcodeObject)
val p = barcode.cornerPoints
var m = barcode.displayValue.toString().trim()
val jsonobj=JSONObject()
jsonobj.put("email",m)
val url="https://192.168.2.11/verf1.php"
val que=Volley.newRequestQueue(this#MainActivity)
val req=JsonObjectRequest(Request.Method.POST,url,jsonobj,Response.Listener {
response ->mResultTextView.setText(response.toString())
},Response.ErrorListener {
response ->mResultTextView.setText(response.toString())
})
que.add(req)
my php file
<?php
require "conn.php";
$user_name=false;
if(isset($_POST["email"])){
$user_name = $_POST["email"];
}
$mysql_qry="select * from exitpass where email like '%".$user_name."%'";
$result=mysqli_query($conn,$mysql_qry);
if(mysqli_num_rows($result)>0)
{
echo"yes";
}
else{
echo"no";}
?>
The error is related to the TLS/SSL certificate associated with your 192.168.2.11 web server. There are a few different ways to solve this problem depending on what your setup is like.
If you have no cert installed on your web server then replace https with http to send over an unencrypted channel.
val url="http://192.168.2.11/verf1.php"
If the web server does have a cert installed then you could have a few issues. Common issues related to the stack trace are invalid certs, using the wrong (or no) domain name, wrong Java code for the encryption type and Java version, issue somewhere in the trust chain, expired cert, etc.
In summary, I believe you simply need to send over http, but if that doesn't work, you should troubleshoot it in this order.
Change the IP to the domain name associated with your cert
Verify you can access your resource in the browser and that the certificate is not expired
Figure out what type of encryption you are using (TLS 1.1, TLS 1.2, etc) and what Java you are using (1.6 or 1.7). There is a key difference between Java 6 and Java 7 as it relates to accessing TLS encrypted resources and I explain it in my highest rated post (as a reference).
If all else fails you will likely need to manually install the certificate in Androids JVM trust store. I believe you can do this from most GUIs and definitely from the terminal if you have access. You shouldn't have to do this, but sometimes you are forced to if the certificate chain breaks. It might not even be your cert causing the issue, it can be any cert in your trust chain.
Please let me know if the initial suggestion works. If it doesn't work please provide the public cert here ( or just the domain name and I will pull it down) and your Java version and I can better assist.

Secure WebSocket (WSS) with HTTPS localhost SSL certificate?

I am a little new to this whole WebSocket and SSL certificate.
So I have created my own WebSocket server on Android side and the website is the client. I was able to make it work with regular WebSocket (ws://) but not secure WebSocket (wss://) due to the fact that it requires SSL certificate.
My question is how can I get a SSL certificate? From what I've read, SSL certificate is based on a domain. I need it for localhost. I need it for something like this address:
wss://localhost:8080/ws/main
How can I go about getting a SSL certificate that will work with localhost.
Thank you for your time!
====================== EDIT =====================
Reason why I am doing this:
I have a Bluetooth service in my Android application that will be getting data from connected health bluetooth devices like Weight Scale and Blood Pressure machine. I have this part implemented already and I want to take this data and pass it to a website. WebSocket seemed easier because the user will have my application open and when they do their weight, it would automatically fill the field on the website with the weight from the Weight Scale. I hope I am making this clear.
To do this, I need to have a way to pass the weight or blood pressure values from Java (Android) to the website that loads within a WebView. So I thought WebSocket would the easiest way.
Please tell me if you think there is an easier way.
Also, I've already tried self-signed certificate and I get the following error:
I/X509Util: Failed to validate the certificate chain, error: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
OR
Exception=javax.net.ssl.SSLException: Error occured in delegated task:javax.net.ssl.SSLException: Not trusted server certificate
Thank you!!!
We faced a similar problem, our solution was to register a subdomain to one of our domains with an A record to 127.0.0.1 and get a certificate for that domain.
local.example.com -> A record to 127.0.0.1
SSL certificate requested for local.example.com
I'm afraid this answer is too late for you however, it can be helpful for others finding this article.

Fetch in react native wont work with ssl on android

When I'm using the fetch function in my react native apps, things work as expected on iOS, but gives an error in android. The error is 'TypeError: Network request failed'. Doing a bit of debugging, I found that the cause of the error seems to be the following: 'java.security.cert.CertPathValidatorException: Trust anchor for certification path not found'.
How come this works in iOS and not on android, and how do I best fix it? Is the fault in react-native, or somewhere deeper?
There is a few workarounds for this issue mentioned here: Trust Anchor not found for Android SSL Connection
However, if you are the server owner. I would suggest to review your server ssl certificate. I think that was because of missing CA certificate in your pem file.
What I have done for my site is I created fullchain.pem by concating content of file.crt and file.ca-bundle as that order.
Then I configure nginx (my server behind nginx) with:
ssl_certificate /etc/nginx/ssl/fullchain.pem;
The original document: https://www.digicert.com/ssl-certificate-installation-nginx.htm
Hope that helps

Using UnboundID SDK with an SSL certificate file to connect to LDAP server in Android app

I'm trying to make a connection to an LDAP server in my Android app, and am using the UnboundID SDK. Recently, a change was made from unsecured to secured LDAP, and I have to change the app accordingly. I have been given the SSL certificates file to validate against. I've already used the file to make a keystore as described here. I've got this keystore file in the assets folder of my app, and am pulling from that. The code below does not currently work, and throws the exception:
LDAPException(resultCode=01 (connect error), errorMessage=('An error occurred while attempting to connect to server place.myserver.com:636: javax.net.ssl.SSLHandShakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found
// code from above link
AssetManager assetManager = getApplicationContext().getAssets();
InputStream keyStoreInputStream = assetManager.open("yourapp.store");
KeyStore trustStore = KeyStore.getInstance("BKS");
trustStore.load(keyStoreInputStream, "myPassword".toCharArray());
TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509");
tmf.init(trustStore);
// my code
SSLUtil sslUtil = new SSLUtil(tmf.getTrustManagers());
LDAPConnection connection = new LDAPConnection(sslUtil.createSSLSocketFactory());
connection.connect("place.myserver.com", 636);
However, the code segment:
SSLUtil sslUtil = new SSLUtil(new TrustAllTrustManager());
LDAPConnection connection = new LDAPConnection(sslUtil.createSSLSocketFactory());
connection.connect("place.myserver.com", 636);
does work (although I was informed by the higher-ups that this would be insecure).
I'm not quite sure as to what exactly I'm doing wrong here, so any help would be appreciated. Also, if there is a better way of accomplishing this than what I'm attempting to do above, feel free to let me know :) I would like to stick with the UnboundID library though, since the rest of the code is already written using that as well, and everything works if I use the TrustAllTrustManager.
It's true that the trust all trust manager isn't secure. It's convenient for testing purposes, but it will allow a bad guy to set up his own server with a certificate he generates for himself and use it to impersonate the real server, or to operate as a man in the middle, intercepting and potentially alerting any communication between the client and the real server. With a more strict trust manager in place, the client should reject the bogus certificate that the fake server will present.
Unfortunately, though, it looks like the trust manager you're trying to use in this case doesn't like the certificate that your server is presenting to it. Because the trust all trust manager allows you to establish the connection, that means that your server does have a certificate and is capable of performing SSL communication, but there's something about that certificate that your trust manager doesn't like. It's almost certainly not an issue with the LDAP SDK, since the same problem should arise with any other LDAP API if you're using the same trust store.
If you look at the result, it has a message of "Trust anchor for certification path not found". This implies that neither the certificate the server is using nor those of any of its issuers was found in the trust store. You'll need to import the server certificate (or the certificate of one of its issuers) into the trust store that you're using. It sounds like you've tried to do that, but since it's not working then something must not be quite right with the way it was done. I'd recommend working wit the directory server administrator to ensure that you're trying to import the right certificate based on the server configuration.

Categories

Resources