How to make a Android client request secure? - android

I have a android application which sends updates about the purchases for the server. What I do now is, I encrypt the purchases and some other shared details into MD5, using the same key generator in server side and Android Client side. But if some one decode the APK file that person can easily make the calls by generating keys. What is the best way to prevent these kinds of attacks?

Use HTTPS to communicate with you server in order to protect data in transit. Do not try to invent a secure protocol. If you want to restrict access to server API's use some form of authentication: username and password (over HTTPS) or better yet some sort of authentication token (OAuth, etc.). If you store keys and/or passwords inside the APK, anyone can extract them by decompiling the APK. If you want to protect against this, you need to use token authentication where tokens expire and can be invalidated if compromised.

Best Solution is that you implement some web service which will return you a access key(will change every time you want to get access key) which you will use every time to communicate with your server in POST method. This is most secure method and being used by every good sites like Facebook, Twitter etc.

Sine my problem was basically about updating the server with in-app purchases, I ended up doing Public/Private key authentication at the server end. Android suggest to verify receipts on client, but we just forward the receipts to server and did validation there using the public key.

Related

Should I encrypt a user's password before sending it to the server?

I want to authenticate a user by allowing him to create a username and password. Since I only find old posts about it, I'm creating this one.
Should I encrypt the password before sending to the server? If so, how should I do it? If not, should I use some specific configuration in my POST request to the server?
Is there any reliable third party api that I should use?
I know that Google has an androidx API for this things, but it's still in alpha.
If you use HTTPS protocol to comunicate with the server the data are already encrypted before beeing sent, anyway I suggest you to execute an additional encryption using Cipher.
PS see this question for more How to encrypt String in Java
You may make a basic obfuscation like Base64 or something like that, as Marco mentioned, HTTPS already secures the channel and information wouldn't be seen by a man in the middle.
Instead of encryption you may add a security validation that the HTTPS certificate is trusted, so that using Proxies such as Charles Proxy is also forbidden.
Encryption assumes an encryption key which needs to be securely distributed. Since the password (or a derivate of it) needs to be stored server side for subsequent authentication I would recommend to send the password in clear text at least when registering the username / password. Of course assuming that HTTPS, enforcing a secure protocol and hostname verification, is used. The benefit is that you don't add an implicit dependency to a specific algorithm to the server API. Instead the server application can hide this as an internal detail when storing the password (or a derivate) in the database. This makes API evolution less painful.
It is often recommended to use certificate pinning (i.e. "hard-coding" a server certificate client side) but this may be overengineering depending on your use case as it will require certificate lifecycle management.
All this said. You probably would benefit from using a third party service (e.g. AWS cognito) for authentication, at least in the short term. This way you can more easily implement 2-factor authentication when creating the account, login abuse prevention, password recovery, etc

SafetyNet api ,get nonce from server rather than the client

I am using this library :
https://github.com/scottyab/safetynethelper
I have read the documentation on Android Deveoloper site and in the repository.
Everything works fine ,but something is not clear to me.
It is indicated that it is more secure to obtain the nonce from the server rather then creating it on the app it self.and why is it better to Pass the response from SafetyNet API to the server
Most commonly the SafetyNet Attestation API is used to decide whether you trust the device and app that is communicating with your server.
As such, you don't really want to be checking the JWS response within your Android app, otherwise an attacker could simply modify your app to remove any verification logic you have put in place. This is why it is better to pass the response to the server, and make any decisions there (you trust your server).
On your server you can verify the response and, if everything looks good, allow whatever action you are trying to protect - maybe permitting a sign-in, or the download of certain data.
Why is a nonce supplied from your server more secure? A nonce that is generated in your app (ie. essentially random and unknown to you) can be changed freely by an attacker. It is better if you control the nonce! This way when you are verifying the JWS response on your server you can check the nonce is correct.
A good approach for generating a nonce on your server may be to hash a session ID, or a combination of the user ID and timestamp.

User Authentification on Android - Security Implementation

I've been mostly creating smaller apps and games for Android so far, but am now creating a somewhat big app with lots of users and more sensible data than a highscore.
My normal approach was to just have a table for all users with passwords, authenticate with a simple Login Screen using a HTTP(S) call and that's it.
There's a few things I want to improve for this app though:
Secure Transmission
If I want to encrypt the user's password, where do I need to do it? On the device, before it's even sent? (In case of unsecure networks, like a public WiFi hotspot) Or better on the server, before writing it into the DB? Or should I just use SQL's encryption?
Auto Login
I want users to be able to stay logged in until the log out - how would I best do that? Not just security-wise, but also for the user experience.
My research shows me that using the AccountManager would be best to save the username and password and authenticate automatically when the app is started. Is there anything more to it, any security risks I'm missing here?
Access control
Usually, I would just expect every call made by an app to be valid, since a user can't access anything but the login screen without logging in. But how do I best authenticate a user's request to make sure that it's not an attacker? I can't just send the username/id with every request, so I probably need like a session token that I generate on each login? Or is there a better method?
Is there anything else I've forgot to think about?
I would suggest you to transfer password without encrypting it but by https. Other way would be to implement asymmetric encryption in your app and encrypt password with public key which you will receive from server.
On the server side I would hash password using some hashing algorithm with salt. And store only hash and salt. When users will log in, you can hash incoming passwords the same way and check hashes on equality.
To make auto login, you need to sign all requests from authorized users with a token. Token you will receive from the server after successful login. This token could be stored in Keystore, or special storage which is accessible only for this application.
Signing could be implemented by attaching to request additional parameter with checksum from all request parameters and token.
Additionally I would suggest you to think about unauthorized clone apps, which could pretend to be your app and call your server side API.

what are solutions to ensure the security of server-side and mobile client communication?

My demands are as follows:
limit requests only from mobile device(iphone or android), that is to say, requests from programme or browser are forbidden.
session based conversation.
server-side can regonize the post data is not modified by other proxy or other ways.
Should consider situation that mobile device may be hacked.
Some of my thoughts to my demands:
corresponding to 1: I want to use RSA, I generate a key and secret, client use the key to encrypt data, server use the its secret to decrypt, and check the key. But how about the key is known to others when the mobile is hacked.
corresponding to 3: I want to use hmac algorithm and secret key to generate signature for every request.
Is there any security problems about my solutions? what are yours?
Updated : I am sorry that I forget to mention all the demands are talked about based on user login.
You generally can't. You need to have your mobile apps authenticate to the server in some way (private account, Google account, SSL client certificate, etc.)
Use regular, cookie-based sessions. Use a solution that provides truly random session IDs and secure with SSL to guard against session hijacking, etc.
Use SSL (HTTPS)
Not sure what that means. If you are doing device-specific authentication, you need a way to revoke accounts, so that a stolen, etc. phone cannot be used.
Last but not least: Do Not Try to Invent a Secure Protocol. Use HTTPS and don't think you can create a secure solution, just because you read a book/blog/article/textbook about it.
Again: Please Use HTTPS.
1) I'm not sure using RSA will fix that, unless all your mobile apps have the same public/private key combos. A browser could just as easily use RSA and encrypt the data.
A way to do this might be to check the HTTP headers coming in for headers inserted by the mobile operator and if those headers can be faked.
It's a hard problem. I'll keep thinking about it and let you know if something comes to mind.
2) For session-based encryption, you can use the Diffie-Hellman key-exchange algorithm to negotiate a session key and then use that to lock requests to a session.
3) sounds good.
4) I think the only way around a phone being hacked is to require users to login, because you need to authenticate the user, not only the device. The other thing is that people share phones, so it may not even have been hacked. It may just have been leant out.
Consider using ASIHTTPRequest api, and use SSL for more protection. For hacked mobile , user login is a convenient way to achieve it and everytime user send POST request you can ask for the pass.

Securing communication from android to a web service

I'm a relative newbie to web and mobile development and especially to security so obvious answers are still appreciated.
I want my android app to be able to log in to a simple web service with a username and password.
What's the best way to send this information securely and keep the user logged in for an entire session?
Do you control the web service? If not then you will need to use whatever authentication mechanism the web service provides.
If you're writing the web service yourself, you have a lot of options.
The simplest is to just send the user's username and password via SSL with every request as a HTTP Authorization: header. The downside here is that you need to keep the username and password stored on the device. That being said, because of the way Android's permission system works, there's very little risk of an attacker stealing credentials off of the device, provided the user hasn't enabled root access.
If you still want to avoid storing the password in plain text, you can send the username/password once (again, using SSL), have the server return an encrypted authorization token, then send that token in place of the user's username/password. See Google's ClientLogin for an example of this. An attacker could still steal the token if they have physical access to the device, but at least the attacker can't use that to gain access to any other sites that use the same password.
There's other options out there as well, like using challenge/response to prevent the server from ever seeing the user's password, using OAuth to provide a common authorization API, and so on. It all depends on what your particular requirements are.
A friend and I are looking to do this same thing, and I think that we've settled on storing a web service key unique to the user on the device, and using that for authentication rather than storing un/pw (this is the second method provided by Trevor above). You'll need to make sure to provide for a means for getting that key onto the device as well.
You can use a server based random key and local imie based key along with users unique token for making a logic .you can put an expiry time for every key

Categories

Resources