How to securely send passwords between Android client and server side application? - android

My current Android application requires users to login with Username and Password.
The Android application calls a REST web service for user login and I do not want to transmit the password as cleartext.
How do I go about securing my users passwords so that the server side can Identify/authenticate each user?
I am currently trying to employ the Jasypt library as follows:-
ConfigurablePasswordEncryptor passwordEncryptor = new ConfigurablePasswordEncryptor();
passwordEncryptor.setAlgorithm("SHA-1");
passwordEncryptor.setPlainDigest(true);
String encryptedPassword = passwordEncryptor.encryptPassword(userPassword);
...
if (passwordEncryptor.checkPassword(inputPassword, encryptedPassword)) {
// correct!
} else {
// bad login!
}
however my server side is written in .NET and as far as I understand the Jasypt documentation the password encryptors employ a random salt.
How can I have my server side code match the hashed users password I am sending it?
All my webservices have HTTPS endpoints, does this guarantee that no one can "see" my users passwords "in flight" when exchanging for an access token?

If you use Https(TLS) then your password is inaccessible to anyone intercepting the network.
You should hash the password string in your server side code not in the client
Also you can use OkHttp CertificatePinner to pin Https(TLS) certificate to your connection for avoiding man in the middle attacks.

A good solution would be to avoid using the traditional Email/Password approach to authentication and go with what another answer here suggested of OTP or One-Time-Password.
Consider the user experience: typing an email and password on a mobile device is cumbersome and annoying and awkward. Then they have to remember their password as well? The average person in the Western world probably uses 10 to 15 apps per day and we want to tax their human memory banks for another password to awkwardly type onto their phone while they are on a packed subway train?
Although it's deceptively challenging to put together, consider One Time Password. With it, a user enters in a phone number as an identifying token.
In theory, every single user has their own unique phone number and thats easy for a user to remember. Since your user is on their Android device, makes sense so far, right? And no awkward typing of email and password.
After they enter their phone number, we then text them a code to the mobile device, which is a 4 to 6 digit number. The user enters that code in the application, thereby proving they are the owner of the device that the phone number is tied into.
The benefit of OTP over Email/Password is that it requires very little memory on the users part. And yes, it's even better than OAuth because what if the user never signed in to a Gmail account or Github account via their mobile browser? Then they are back to Email/Password awkward style authentication for mobile device.
One-Time password is user friendly.
But you say okay, but is it secure and more importantly to the question: How can I have my server side code match the hashed users password I am sending it?
Right, so One Time Password technology is always an ambitious project to undertake IMO.
So we need to persist the code that the user should be entering into the device so we can compare it at some point in the future. When you generate a code, save it to Firebase so at some point in the future you can reach back out to Firebase and say the user with phone number 212-555-1212 just sent you the code 1234, is that the correct code?
So, the way Firebase works with OTP is you can store the code in Firebase. The challenge though is actually texting the user a code. This is an actual SMS message. To handle that, you can't use Firebase alone, you can integrate the extremely popular Twilio. Twilio is all about interacting with users via phone SMS messages and so we can make use of Twilio to text the user a code.
You can also take care of authentication or user system inside of Firebase. Once the user enters an OTP, we generate the JSON Web Token through Firebase.
So all the JSON storage and all the info that reflects who the user is, all that can be saved on Firebase.
But there is another part to that question I have not answered:
How do I go about securing my users passwords so that the server side
can Identify/authenticate each user?
Okay, so you need to compare the code on some server. It can't be Firebase because Firebase is simply a datastore, it is a place to store JSON data, it does not give us ability to run custom code.
So do you write a server for the comparison of codes? We do NOT want to do this comparison on the user's device.
So what do we do? Also, how do we generate a code? Don't use the user's device for that either.
So where do we generate the code? We know to use Firebase data storage to store the code, but how do we generate it?
That's a good job for Google Cloud Functions.
So Google Cloud Functions are code snippets that run one time on demand on Google servers. GCF have tight inter-operability and integration with Firebase data stores.
We can add some logic or processing to the data sitting inside of Firebase. GCF will allow you some custom logic to generate your codes and save them to Firebase and GCF can also compare the code once the user sends it in.
AWS Lambda and GCF are nearly identical in functionality so that could be an option as well.

You have to be careful about what you do. Consider implementing a common two-factor key-sharing algorithm, such as TOTP.
A pretty uncommon, but really good practice, is the client-side hashing. This of course doesn't stop the hacker from logging in to the user's account, but it stops them from obtaining the potentially reused plain-text password.
I recommend that changing E-mail and password are done under the reset password formula, such that E-mail/SMS confirmation is required. And finally, as you do it is extremely important that the connection, where the login happens is secure, for example, https/tls.

There are couple of things you need to consider while implementing authentication and authorization between client(Mobile app) and server.
Firstly, what authentication and authorization mechanism does your server have to request api endpoints? (Is it Two-Factor Auth? Is it bearer token (grant-type username and password) based? Is it bearer token (grant-type access-token) based?
Secondly, as you have mentioned server programming is .Net based but can you be more specific whether your service layer (Api ) written in WebApi 2 or OData ?
Finally, does your server allow to communicate with or without SSH i.e. HTTP vs HTTPS? If it's with SSH then its okay to transfer user credentials i.e. username and password over othewise it will be never secured to transer credentials over HTTP.
Then only it comes at your end i.e. in Android Mobile App to impelement the authentication and authorization mechanism as per server requirement to communicate with api endpoints.
For example, my server requires to implement token-based authentication (bearer token and grant-type password) to make every server request (GET, POST, DELETE, PUT) and I have implemented using retrofit client as like :
public Retrofit getRetrofitClient() {
// first add the authorization header
OkHttpClient mOkClient = new OkHttpClient.Builder().addInterceptor(new Interceptor() {
#Override
public Response intercept(Chain chain) throws IOException {
Request newRequest = chain.request().newBuilder()
.addHeader("Authorization", "XXXXXXXXXXXX")
.build();
return chain.proceed(newRequest);
}
}).build();
if (retrofit==null) {
retrofit = new Retrofit.Builder()
.client(mOkClient)
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.createWithScheduler(Schedulers.io()))
.build();
}
return retrofit;
}
and my service is
public interface LoginService {
#POST("/api/token")
#FormUrlEncoded
Call<TokenModel> getToken(#Field("username") String username,
#Field("password") String password,
#Field("grant_type") String grantType);
}
Now I can use this token in every request to commuicate with server. I don't need to transfer username and password over public internet rather I use just token and it has 24 hours expiration ( as server has implemented this token expiration date).
Hope it helps you to understand the authenticaiton and authorization mechanism between cleint(Android Mobile App) and server.

Related

Is Captcha good solution for android authentication?

I'm developing an application (as a part of team) for android that interacts with server (asp.net web service) for synchronize and update information in client side.
for preventing attack to server we use SSL connection and also authenticate users with soap header message contains username and password.
here is the scenario for synchronization:
users send web service request with header contains : username , password , time of request , and(for preventing man on the middle attack) hash code of all three parameters(username+password+time) as message signature
web service check that :
is this a new message by checking the signature of message stored in server
if this is a new message (and its not duplicated) then check that signature is true by hashing all three parameters(username+password+time)
then check expiration time : is the message new ( in 5 minute ) for expiring old messages
Authenticate username and password
validate datatype and length of parameters ( in this case only time of device's last sync )
response to request
device get the response as xml file
the question :
because of this scenario we have to give user's devices authentication information so they could interact with server in future and also we don't want to get any information like username and password from users ( for user experience purpose! )
so we build a Web Handler Captcha in server and when users are new, we send them a captcha image generated by their device code(it is uid generated by device something like : https://www.server.com?appid=00000000-0000-0000-0000-000000000000 ) and when if user sends the correct captcha to server we add a new user to our database ( auto username and random password ) and save to the android's account manager for future use
in your opinion is this a good approach for authentication and security?
Thank you for tips
Https and a method to get a sessionId is enough security for most apps, anyhow my opinion:
Unless you include a secret within the hashed variables a "man in the middle" can change the parameters and forge a valid hash.
I would recomend a registration method. It's going to take device information as parameter, and the captcha if you will.
It's going to return a deviceId and a deviceSecret. The deviceSecret must not be transmitted again, just used as part of the hashes.
Also consider using a counter instead of time. It can help against replay attacks and it's easier overall.

How to implement server side sessions in node.js with express for an android app?

Hello all i am making an android app in whiich i have multiple account login at a time now my question is that i for multiple logins i should use sessions to verify every account user that is logged in. Now i am using express on the server side i have read a lot of documentation on storing sessions in node.js
Express-session (Though it is only good for development but not for production but not for my app)
Cookie-session
connect-Redis
connect-mongo
I have also heard about json web tokens where i can generate unique tokens and then i can pass the tokens to the client using res.json({user_id:"user1", token: "generated_token here"})
I have also heard about passport but dont know how it is going to do this also as in passport i use express-session by default will it be good for production or not ??
Now my first question is i have read all of there docs and nowhere it is mentioned where i am creating unique tokens for every user that is signing up.
Second question as i am using my server for android app there will be no use of cookie i will be sending user token as in parameter req.body.token now how to cmpare this with current user_id.
Actually i dont get the flow of control i mean how everything is going on in session in node.js. Also what is this secret is this thing generating unique tokens or what. Also i mean about 100000 of users are registered for my app now please tell me accordingly which way should i use for my app.
I have asked this question previously but there i did not mention that as i am not making a website how to do this(As in my case there will be no use of tokens)
I know this question i am asking is very vague but please bear with me i just want to understand how sessions are used in node.js
Thanks Anways
I'll try to answer this, but it is vague (as you pointed out). I'm going to make an assumption that your Android app is a native Android app and is going to be connecting to some sort of NodeJS backend in the cloud that is based on ExpressJS. If that's not the case, please clarify your thoughts in an update to your question.
The best idea for this specific scenario is to look to the cloud provide. Azure App Service Mobile Apps, for example, allows you to implement authentication - it eventually returns a JSON Web Token (http://jwt.io) to authenticate each request.
If you don't want to be beholden to a cloud provider, but want to run it yourself, you are going to have to implement the token generation and checking yourself. This generally follows the form:
Set up a WebAPI endpoint (maybe /signin) which takes whatever token the identity provider gives you, verifies the information and returns a JWT - there is an NPM module (jsonwebtoken) for producing the JWT. Ensure the JWT includes the identity of your user. I tend to use email address for the identity.
Your Android application will do a WebAPI request to your backend with an Authorization header, the value of which is "Bearer "
Your NodeJS API will use JWT authorization to validate the JWT and extract the user identity so you can use it in your API logic.
The important thing to note in this specific scenario is that your backend code is implementing a WebAPI - there are no cookies nor sessions in the API. The only thing that is linking the user from the client code to the backend code is the JWT.
As a short piece of code, here is how you verify a JWT:
var express = require('express');
var app = express();
var jwt = require('express-jwt');
var jwtCheck = jwt({
secret: new Buffer('your-jwt-secret', 'base64'),
audience: 'your-jwt-audience'
});
app.get('/api/protected', jwtCheck, (req, res) => {
// Your code here
});
app.listen(process.env.PORT || 3000);

Verifying user credentials with REST API?

I've set up a REST API on my site in order to return information from my database.
I'm implementing login and registration on my app right now. However, I'm not sure how to handle verifying user credentials (checking if an email is already registered, if a password meets its requirements, etc).
Since my REST API is not open to the public, would it be safe to pass the data like this:
/users/verify/email/{email_address}
/users/verify/password/{password}
Or is there a better (safer) way to do this? In other words, how can I authenticate and validate users when the login/register?
In REST you're talking about resources. A resource will have some state expressed through their properties.
With your example I would ask myself: "why verify an email", "why verify a password". Because you want to verify if a user can be registered.
So your resource will not be an email or a password but a user.
Verification is an action. Something which does not go well with a REST architecture.
What do you want to verify? You want to register a new user but also verify if he's allowed to register. So you'll try with some conditions to add a user to your collection of users. In REST with HTTP this can be done with a POST which acts like an add(User). The logic behind the request can then implement the verification rules on the user.
To post data just use the content body and use the headers for additional info. So I'd change my API to:
HTTP method: POST
Path: /users
Content-Type: application/json
Body:
{"email_address":"qsdfg#sdfgh.com", "password":"qlmkdjfmqlsk"}
Which simplifies your API to a single entrypoint for adding a user. Allowing or refusing to register the user can be communicated through the use of HTTP status codes and messages.
Of course sending passwords in plaintext is not a good practice but you can setup a secure connection with SSL or TLS to communicate.
Sending sensitive data in a URL is not a good practice btw. Servers can log the url which will show everyone with access to the log the password of the user.
The login is a bit different but not that much.
You'd need a resource which uniquely links a user to his conversation with your system.
HTTP method: POST
Path: /authentication
Content-Type: application/json
Body:
{"email_address":"qsdfg#sdfgh.com", "password":"qlmkdjfmqlsk"}
Response
Status-Code: 200
Content:
unique-id-to-my-user
The authentication could call your user api to enforce the rules and then generate the id.
You could use an OAuth2 implementation to handle this.
If your web service is Asp.Net WebAPI which will return an access token for the valid user, you can use Http POST request with username and password as body content.
For sample code, please take a look at my answer in the following question
Implementing Oauth2 with login credentials from native login page
For better security, use Https instead of Http.
Hope this helps!
You can use POST method.
/register with name, email, password for User registration
/login with email, password for User login.
Just make sure that you do not pass the password in clear. Perform some kind of encryption on it.

Rails api and native mobile app authentication

I know there is a lot of information about this topic, but I can't find any that is up to date.
I see topics like this one relating to rails and android authentication but I see that TokenAuthenticatable is now removed from devise.
My question is simple: is there a good way to authenticate users from native Android and iPhone apps using Rails 4? Does anyone know of good tutorials or articles that provide a solution ?
Adam Waite Adding a bounty:
I have just opened a 500 bounty on this question because I can't find the correct practice for authenticating a user from an iOS app to a Rails API anywhere. This is what I was considering doing but have no idea if it's secure or not?!:
Let's assume we have a User record. A user has signed up for an account which has created a User record in the database with an email column and a password_digest column.
When the user signs-in I would like that user to remain authenticated on the mobile app until explicitly signing-out.
I imagine we're going to need a token based authentication. I would perhaps create an ApiKey record when the User is created and have that saved as an association on the User record.
When the user signs in/up, the response will contain an API token (something like SecureRandom.hex) which will be saved in the iOS Keychain and used with all subsequent requests to verify the user by passing it in a header and verifying it using something like:
before_filter :restrict_access
private
def restrict_access
authenticate_or_request_with_http_token do |token, options|
ApiKey.exists?(access_token: token)
end
Is this secure? Should I be refreshing the token with every request and including it in the response?
What other options do I have? What do the likes of Facebook, Twitter and Pinterest do?
I am aware of OAuth2.0, but is that not for granting external applications?
Is there a gem that manages any of this?
Sorry, completely unsure here.
500 to the best answer.
Gist of a solution from my research. Feel free to edit, correct, invalidate, etc.
SessionsController < ApplicationController
skip_before_filter :authenticate_user, :only => [:create]
def create
user = User.where("username = ? OR email = ?", params[:username_or_email], params[:username_or_email]).first
if user && user.authenticate(params[:password])
api_key = user.find_api_key
if !api_key.secret_key || api_key.is_expired?
api_key.set_expiry_date
api_key.generate_secret_key
end
api_key.save
render json: api_key, status: 201
else
status: 401
end
end
Note the ApiAuth.authentic? method and the request object. The request must be signed with an HMAC algorithm on the client.
ApplicationController < ActionController::Base
respond_to :json
force_ssl
protect_from_forgery with: :null_session
before_filter :authenticate_user
private
def authenticate_user
if authenticate_user_from_secret_key
return true
else
head :unauthorized
end
end
def authenticate_user_from_secret_key
userid = ApiAuth.access_id(request)
currentuser = userid && User.find_by_id(userid)
if ApiAuth.authentic?(request, currentuser.find_api_key.secret_key)
return true
else
return false
end
false
end
User creation/registration
UsersController < ApplicationController
skip_before_filter :authenticate_user, :only => [:create]
def create
user = User.create(user_params)
if !user.new_record?
render json: user.find_apit_key, status: 201
else
# error
end
end
Api key model. Similar to api key model in #352 railscast only difference is ApiAuth key generation.
class ApiKey < ActiveRecord::Base
before_create :generate_secret_key, :set_expiry_date
belongs_to :user
def generate_secret_key
begin
self.secret_key = ApiAuth.generate_secret_key
end while self.class.exists?(secret_key: secret_key)
end
User model.
class User < ActiveRecord::Base
has_secure_password
before_save :ensure_api_key
has_many :api_keys
def find_api_key
self.api_keys.active.ios.first_or_create
end
On the client side the HMAC algorithm must be used to sign requests.
The code is from:
[SHA1 HMAC Key generation/authentication] https://github.com/mgomes/api_auth
[Controllers & Models] https://github.com/danahartweg/authenticatable_rest_api
I've had this issue, I'm an API developer. You could do it the hard way with tokens and custom authorization, but I will tell you what we do with our application, which serves users in the six digit figure.
At least for iOS, the device will handle sessions for you, meaning that if a user on an iOS app makes a POST request to /users/sign_in with the parameters
user: {
password: 'mypassword',
email: 'testuser#example.com',
remember_me: true # optional
}
the iOS device will store the session for you, safely and persistently.
Now, if you want to go the OAuth 2 route, I actually maintain a gem for rails 4 called OAuth 2 providable, to which I added a pretty cool feature that allows you to have the user pass through the "authorization" screen, because obviously if you developed the software you don't need the user to confirm that they trust you.
If you do decide to use OAuth 2, you will need to use what is call the implicit access token.
This is the long and very boring OAuth2 spec for that
The rails 4 project can be found on github
https://github.com/bwheeler96/devise-oauth2-provider-rails4
If you're not on rails 4, you can use the original gem
https://github.com/socialcast/devise_oauth2_providable
By the way, the gem needs work so if there's anyone reading this who wants to help make it better, please by all means fork this repository
You are on the right track, but the user's token should only be used to identify which user is making the request. You still need some kind of authentication since, as you speculate with changing the token on each request, a hacker could intercept the data stream, get the token, and then "be" that user in subsequent requests.
By changing the token on each request, you eliminate the interception issue, but once someone has intercepted the token, they can then further exploit the system by continuing to intercept it and even modifying the response. One solution to this is to use HMAC (which is used by Amazon Web Services). It is an algorithm that provides a signature (hash) for your request that is unique for every request, doesn't require a changing key, and cannot be predicted for future requests.
There is a ruby gem for rails that implements HMAC on the server side for signing HMAC requests as well as generating them when doing server-to-server communications. For client-to-server requests as in your case, you need to generate the signature on the iOS or Android side and authenticate them on the server.
Consider the ApiAuth gem to do the work on the server side. On the iOS client side, consider the HBHMAC library for generating the signature. Take a look at the ApiAuth's specific implementation as it adds a timestamp to the data to prevent replay attacks, so you may need to add a field to your data before passing it to HBHMAC.
In summary, using HMAC authentication will avoid man in the middle attacks and replay attacks by utilizing a one-way hashing algorithm that prevents attackers from generating authentic requests even if they are able to intercept valid requests.
If you want to use OAuth2.0 in ruby on rails, you would be use Doorkeeper, you can see an example (not free) here:
http://railscasts.com/episodes/353-oauth-with-doorkeeper
But you can use a token with SecureRandom.hex, a example (not free) for this is here (in level 6):
https://www.codeschool.com/courses/surviving-apis-with-rails
I hope my answer help you!

Android Facebook app integration with GAE

I'm thinking about how to solve the next problem:
An Android App which I want to connect to facebook, and to a Server backend(Srv).
Server backend(Srv) which I want to connect to facebook.
The server will run a task that will Get all the Friends of the user(on fb), and the user Statuses(on Fb), and store them on it.
Base assumptions:
I use android as a Mobile device
Server is GAE
Entity key in GAE is the user’s FB-id
User Entity contains:
User fb_id
User verified list(FB_ID String)=> friends of the user that have the app) // maybe use HT?
User statuses list(Status text, date, url)=> whatever I can get from a Status of a user in facebook..
Main questions:
Is the Data representation thought out? can it be better?
How do I handle a situation where two users which are connected to one another add the app at the same time- how can I avoid overlapping?
Should the device Authenticate itself, also with the GAE server?
How to Authenticate GAE with FB
Algorithm:
Android side:
User login and get access token from FB
Posting to my server(Srv) FB Token & myUserFBId // Should I use REST protocol or HTTP
POST?
Server side:
A Servlet handles the POST
{
Query FB ->for the user's friends ids(into friendList = arrayList<FBItem))
foreach FBItem item in friendList
{
//check which FB-ids are in my DB
friendEntity = getKey(item.fb_id)
if(friendEntity != null)
{
// friend exists
verifiedFriendsList.add(item.fb_id) //verifiedFriendsList is ArrayList<String>
friendEntity.getVerifiedFriendList().add(myUserFBId)
}
}
Query FB ->for the user's statuses(into statuses = arrayList<StatusItem))
add new FBEntity(myUserFBId, verifiedFriendsList, statuses) to DB }
Thanks
I have not done anything like this but I think you will need to
Ask user to authenticate your application to use FB- Read about OAuth Api of Facebook
Once your app is authenticated with sufficient permissions you can get users data as per your requirements .
Once you get the data you can process it.
Oauth on FB is what you are searching for..
I'll give you my 4 cents:
The questions that should lead you in developing the DS are: (A) On the
server side, How does the data persist? to a File? to a Database? (B) How much of that data is required to perform the calculations you want done, and how do plan to access it (for example, for an O(n) run, I wouldn't use a HashTable) (C) How does the persist / de-persist work? with an ORM? custom queries?
About concurrency, you'll have to explain what's bugging you. People sign in to SO simultaneously all the time.
3/4. Not an android developer, can't help.

Categories

Resources