Android service communication, with Raw bytes over SSL - android

I have given a 3rd party API to access a service to get some work done from a client Android App.
There they have provided Service hosted URL and the PORT number and asking to send raw bytes (Request data) over a SSL IP Socket connection to it.
Steps they Ask to follow
Open a SSL connection to Service. The SSL Connection will be mutually authenticated. (Self signed certificate)
Send request data in a CSV structure format (Raw bytes over a SSL IP Socket connection).
The App now will receive a response (byte stream) from the SSL connection.
Questions
Is this a standard way to do in Android?
I have previousely communicated with web services by sending request data over HTTP/S (POST and GET) methods but wonder how to do this. Read many tutorials (LINK1) but still bit not exactly sure how to do this.
Would like to here what exactly(steps) I have to do in here. Thanks....

Using SSL is standard practice on any platform that needs to protect data. It has nothing to do with Android specifically.
In an Android client app, you can use the SSLSocket class. It will handle the SSL portion for you, so all you have to focus on is sending the CSV data and reading the response data.

Related

Is SSL required for Windows and Android applications?

Recently I read quite a lot about SSL, but all articles concerned webpages. Let's suppose I'd like to make an internet service with webpage, mobile app and C++ windows app. Users must have their accounts, so they need to send to a server data like username, password, etc. As a webpage I'd like to have Angular app and some backend technology (Node for example). Windows and Android app will use the same backend server as Angular, and they will connect to it by REST API. If I install SSL on the server, where web apps are stored (both front-end and back-end), all the data sent in HTTPS requests should be safe. But what about the data sent from Android app and Windows app (made in MFC in my case)? If I have understood those articles well, internet browsers encode sent data, and decode received one themselves. But do I need to handle HTTPS connection in Android and Windows application myself?
For android, if you will use self signed certificates, you'll have to express how to handle that on your app. See how it's explained here https://stackoverflow.com/a/997495/4242450. But overall if you are using trusted certificates, there's no need to worry about SSL handshakes, encryption or decryption data for yourself.
Here's a piece I found on https://developer.android.com/training/articles/security-ssl
Assuming you have a web server with a certificate issued by a well known CA, you can make a secure request with code as simple this:
val url = URL("https://wikipedia.org")
val urlConnection: URLConnection = url.openConnection()
val inputStream: InputStream = urlConnection.getInputStream()
copyInputStreamToOutputStream(inputStream, System.out)

HTTPS url not encrypted

I'm using Charles proxy to fetch all the requests coming from my Android app to a webservice.
The thing is Charles shows me the complete request, meaning I can see the whole URL, headers and body so I can see www.example.com/rest/resource/param1/param2,
the JSON I send with it and also the authentication header.
After reading several posts like this and this one I thought the good part of working with the TLS was that one could only get the domain name from the URL, in this case www.example.com
To make sure it's not the client's fault, I requested the webservice resource with Retrofit and HttpsURLConnection and I could see the whole request both times.
I guess also the certificate is properly installed because it is shown in the browser every time an https request is made. Am I missing something else here or is this the normal behaviour?
So far I couldn't find a reason for this to happen so any help will be appreciated.
To debug with Charles proxy you must install a certificate on your browser (client).
With https the URL is encrypted.
But because you choose to use that proxy, your browser establish a secure connection to that proxy, and the proxy to the website. So, only 1) you, 2) the proxy 3)the website can decrypt the https traffic.
By installing a CA certificate on your browser, you allow the person detaining the corresponding private key (in your case, your proxy) to impersonate (so, decrypt with a MITM) any website.

Android GCM : understanding XMPP

I'm trying to implement a XMPP protocol in my GCM using app, but even after searching extensively, I don't understand the concepts behind it.
Also, maybe I don't really need XMPP for what I want to do with my app, but I like to learn things.
Let's take this example of what I could do with HTTP :
my app send "hello word" and the regId to my little personnal server : url.openConnection(""), then OutputStream for sending POST data and InputStream for getting the response
the server, at this url, put the "hello word" message in a database with the regId, and then use the curl library of php to send data to GCM servers as a json string like {"myResponse":"I'm not world I'm Dan"} (using a test destinator id, in an emulator)
GCM server do his business
my app (maybe on another phone) use an IntentService in a WakefulBroadcastReceiver that get the message as intent.getExtras().getString("myResponse")
This works well and I could send messages from one phone to another using my app, and collecting data on my server the way through.
Very little Question
Is this way of handling HTTP ok theorically ? (I saw a lot of posts and tutorials, especially Google ones, but still not sure)
Big real Question
What are the steps to do the same with XMPP ?
I don't want a tutorial or pieces of codes, I want to understand the way the info goes through this protocol I don't know well (I managed to install ejabberd on my server and use pidgin on my PC and Xabber on my phone).
Official definition:
The Google Cloud Messaging (GCM) Cloud Connection Server (CCS) is an
XMPP endpoint that provides a persistent, asynchronous, bidirectional
connection to Google servers.
Establishing a connection with CCS is the first and most important step here. Once you are done with this and maintain a long-lived connection, other parts are not that tricky.
Some differences between the two:
1) Unlike HTTP, with XMPP messages you do not need to include Authentication headers with every payload since server is authenticated at the time of connecting and we are maintaining the same connection.
2) CCS uses XMPP as a Transport Layer and therefore after you have successfully established connection you can exchange stanzas.
3) You could keep using HTTP for downstream though and use XMPP only for upstream if you wish.
4) Instead of registration_ids param use to: in XMPP and we can only send to one RegID through one stanza.
So if I were to explain how your example would work with XMPP:
- Establish a connection with CCS
- Send an upstream message to your server from the client "Hello, World!"
- Acknowledge once your server receives this message by sending ACK to GCM
- For downstream message you have choice of using either of HTTP or XMPP
- But if XMPP: receive, save in database and when sending response ({"myResponse":"I'm not world I'm Dan"}) back to the client (same or different RegID) send a downstream stanza to CCS; CCS will send ACK/NACK to acknowledge that it has received the message
- You will also receive delivery_receipt (if requested) once the client app has received the message.
Other than this, you can understand more in depth by reading the official documentation which I have linked throughout the post.
Hope this helps!

How to implement Kurento Client JS with your own "Tomcat signalling server" on Android using a secure SSL connection to KMS?

So this is a two part question:
Part a: I'm trying to implement a secure connection to the KMS. From the documentation, I've understood that KMS Configuration file would need to be updated with the SSL certificate and then the HTTPS connection from the client can be made. Please let me know if there are any other steps that are involved in achieving SSL security.
Part b: From a better understanding now and from comments from a previous question I posted, Kurento Utils does not connect to KMS directly (this was an fyi and a clarification I received and I wanted documented here just in case). Now I'm trying to use Kurento Client to connect to KMS and I'm trying to understand the role of ICE/TURN/STUN servers acting as negotiators in the middle. If I were to specify my own server URL, I'm assuming that I would not need to include "freeice" and "normalice" and instead specify my own server's URL. In the code snippet below taken from the tutorial on github, I'm assuming that I would need to replace the argument for ice_servers to point to the url where my server is running? Or since this is the client, do I really need an ICE server because as said from the first statement, the utils don't connect to the KMS but the client can, right? So if I were to specify the Kurento URL for "ws_uri" parameter, then I won't need to even use ICE servers...right? I don't really understand the concept of ICE/TURN servers very well in terms of how they integrate with Kurento and hence, I would like to understand in English as to what changes would I need to make in order to get this to work. I will bang my head to write the code myself! Thanks much in advance!
`
var args = getopts(location.search,
{
default:
{
ws_uri: 'ws://' + location.hostname + ':8888/kurento',
file_uri: 'file:///tmp/recorder_demo.webm', //file to be stored in media server
ice_servers: undefined
}
});`
Answer A
Only this and nothing more... at least for KMS. On the client side, you'll need to specify the WSS port and so on.
Answer B
Your client might need a STUN/TURN server, and that's independent of where KMS is located. STUN and TURN are used in the candidate harvest process, to discover the network topology of your peer. You have two peers: KMS and your Android app, and both need to have, in their SDPs and during the negotiation, a candidate that is reachable by them (app will connect with KMS and viceversa) If both peers are on the same network, you can go without using STUN/TURN. The moment you have a NAT in between, you need at least STUN for that peer to be able to harvest candidates that have the public IP on the other side of the NAT, which is not known by the peer unless STUN is used.
TURN is used as a relay server, and it is needed in a small set of cases. If you are almost certain you are going to use TURN, you need to have that in a machine different than KMS (it makes close to no sense to have both the relay server and the media server installed together)
So the answer is yes, you are most likely going to need STUN/TURN in your clients.

SignalR Android and Headers

I used to use HTTP Headers to pass some authentication data from my SignalR Client (Android) to our SignalR.
After updating my project to use the lastest source from GitHub, this technique has stopped working.
After some research, I noted that this happens because the new default transport used is websocket, and websocket donĀ“t allow us to use Http Headers.
So,
Is there any way to use HTTP Headers with SignalR and WebSockets transport?
If no, how could I pass some parameters to my server? Is there any other option available than using QueryStrings?
Thanks!
In general you should be able to set headers in the client and it should send them to the server when the websocket is being opened (the connect request). Not sure what client you use but this this is possible when for sure with C# client. However, as opposed to other transports, sending or receiving messages when using websockets does not require creating new HTTP requests and therefore if you set headers after the websocket is opened they won't be sent to the server until the next time the client has to send an HTTP request which is either when the client needs to reconnect or when the connection is stopped.
Another option (if your client does not support headers for websockets) is to send parameters using query string. On the server side you can get the request using the HubCallerContext.Request property which allows you accessing the query string like this (you can also read cookies the same way):
Context.Request.QueryString
Again, query string will only be sent to the server if the client is making an HTTP request, which in case of websockets after the connection is established happens when the connection is reconnecting or is being stopped.
Finally, you already have a connection to the server so maybe you can just send your parameters using this connection which should work regardless of the transport you are using.

Categories

Resources