I am using JSONStore to store some data in my project but my problem is that I want to store a key that is used to unlock the data.
Does MobileFirst provide any way to
Securely store a key at client side or server side.
Is there any way that I can get the key from adapter or unlock the
JSONStore by connecting to adapter.
I believe you want to encrypt the data inside of a JSONStore collection and at the same time you want to be able to decrypt the collection without requiring the user to enter a password.
Approach 1: Client side
If you want to accomplish that in iOS you could use Touch ID for that purpose. You could read up more on that by going to https://www.ibm.com/support/knowledgecenter/SSHS8R_7.1.0/com.ibm.worklight.dev.doc/devref/t_setting_up_touch_id_jsonstore.html
For Android there is no out-of-the box integration but staring in Android Marshmallow (6.0) there is an API for the fingerprint scanner which you could also use. https://developer.android.com/about/versions/marshmallow/android-6.0.html#fingerprint-authentication
Basically with the approach mentioned above you are creating a random password and storing it securely in the device. Then the device prompts the user with the authentication (fingerprint scanner or pin code) and then if it's successful you will get access to that random password.
Approach 2: Server side
In this approach you will use an adapter to hash a token/string sent from the client. For this to work you will need to use something that remains constant i.e., device id WL.Device.getID() https://www.ibm.com/support/knowledgecenter/SSHS8R_7.1.0/com.ibm.worklight.apiref.doc/html/refjavascript-client/html/WL.Device.html#getID
app.js
WL.Device.getID(function(response){
var id = response.deviceID;
var req = WLResourceRequest('/adapters/Util/hash', WLResourceRequest.POST);
return req.sendFormParameters({
pass: id
});
}).then(function(response){
var passwordHash = response.responseJSON.hash;
// open JSONStore collection with the passwordHash
});
In your adapter you can hash your password/device id then return it to the device to open the JSONStore collection. You can check the following post How can I hash a password in Java? if you want to hash passwords in your Java adapter
This approach is a bit tricky since you will need to authenticate the somehow to make sure you are only opening/decrypting JSONStore for the legitimate user.
Related
I'm working on a desktop app using NeutralinoJS (an Electron alternative).
The app has password authentication for users, but it won't have access to the internet, so the authentication must be done on the client-side.
The data used for authentication is stored in localStorage and therefore it can be accessed by anyone who has access to the client PC. So, I can not store passwords as is. I need to transform them using some computationally expensive webcrypto method/algorithm.
At first I was thinking to use digest
const hashToStore = crypto.subtle.digest(algorithm, data)
But the digest algorithms are fast and it would be easy to bruteforce the password.
Then I realized I need to generate a key and use encrypt method:
const key = crypto.subtle.generateKey(algorithm, extractable, keyUsages);
const result = crypto.subtle.encrypt(algorithm, key, data);
The problem here is that I need to store generated keys in localStorage as well as encrypted password. Here's the list of algorithms.
Which algorithm do I use? Any advice?
I want to validate my RESTful API using token authentication. Two key options provided are https://github.com/tymondesigns/jwt-auth and Laravel's own inbuilt token authentication.
I'm unable to make jwt-auth work for me even if it looks the most promising, so I decide to check on Laravel's implementation.
It is pretty straightforward. Create an extra field api_token in users DB, generate a random string and store it against the users record IN PLAIN TEXT, then any request the user sends they should append the api_token, which you shall authenticate by checking its existence in the DB. Just that.
Isn't that like storing passwords in plain text because anyone who happens to have access to the DB is as good as authenticated? Isn't there an outright security risk there? Someone help me understand this one.
Also, how does one handle things like invalidating the token, giving the token an expiry period, and such?
for Similar Case I am not using any external plugin, while Laravel already ship a project called Lumen which is best suitable for Restfull web service,
I am storing the encrypted hash string as api_token in the user table,
and in my mobile application i let the users authenticate by username password first time and then i store the decrypted token in the mobile to maintain the user state for subsequent api calls, key point is i am storing the decrypted user token in the mobile and whenver i receive the token in server, i do comparison to match both of them using the same encryption function i have used before,...
in this case you have to come up with your own encryption algorithm since you need to use the same algorithm to decry-pt in the client,
or else an easy way is to copy the user password hash string in the api_token field and store the user password in the client side,
but you have to make sure the security of the client application,
if you consider native android, i will use sharedpreference in private mode which is secure....
if(Hash::check($password,$user->password)){
$response['success'] = 1;
$response['message'] = 'You have Connected to Server Successfully';
$response['api_token'] = $user->api_token;
}else{
$response['success'] = 0;
$response['message'] = 'Authentication Unsuccessful';
$response['api_token'] = '';
}
There is a common requirement of storing user credentials securely (user id / user password) in the App and use them automatically next time the App starts, but I'm not being able to figure out how to do this without user interaction.
Using JSON Store I need a password to encrypt the information, so if I store user credentials in the JSON Store I will need to ask to the user for the password used to encrypt the information.
A solution I figure out is to store the user id in a JSON Store without encryption and the password in a JSON Store encrypted with the user id as password. May be this solution provide a bit more security than not to encrypt anything but I think is not a complete solution.
As explained in the comments this is a really bad idea.
Is there any solution to store user credentials securely and recover them without user interaction?
You can use the Keychain API on iOS. Android doesn't seem to have an equivalent API.
The most complete solution I figure out is to store the user id in a JSON Store without encryption and the password in a JSON Store encrypted with the user id as password. May be this solution provide a bit more security than not to encrypt anything but I think is not a complete solution.
I would strongly advise against doing that, if you store the encryption key (the user id) in plain text, then the attacker can simply use that to get to the password.
Update (Aug 27, 2014)
You should consider:
Hashing - You could hash values you want to protect. These are one-way functions, so you can't get the password back once you hash it. However, you can verify that the user provided the correct password. For example: First login you store( hash(password) ) then on next logins you compare if hash(password_provided) == stored_password_hash. If it matches, the user provided the same password. You should also use a salt.
You could give the user the ability set a pin using some library like ABPadLockScreen (you could probably find or implement something similar for Android too). You can then use the pin as the PBKDF2 input to generate an encryption key (JSONStore will do this for you when you pass the pin as the password). I would advise in favor of letting users only try a small amount of incorrect pin numbers, especially if the pin is only numeric and short, that way they can't easily guess the pin by trying various combinations. The idea here is that a pin will be easier to remember and type than their password.
FYI - There's a Stack Exchange site similar to StackOverflow but for security questions here.
I'm trying to achieve the following through Worklight.
My app has two sets of features. One set of features can be accessed only when the app is connected to the server and the user is authenticated. Another set of features can be accessed offline but they require data from an encrypted JSONStore.
I have a JSONStore on the client device which is initialized using a password. Therefore, the data in the store will be encrypted. Also, this JSONStore is synced to a database on the server through an adapter.
I have also setup another adapter which authenticates the user by using another set of credentials stored in a database. The user can be authenticated only when the app is online.
What I want to do is to unify these two approaches so that the user needn't enter two sets of credentials to access these two different sets of features. One possible solution that came to my mind is just to encrypt the JSONStore and perform the adapter authentication without the intervention of the user. But I don't think that it's secure.
Any advice or approach to solve this issue?
The following is just an idea, I'm not a security expert.
Requirements:
To use the offline features you must have been online and authenticated at least one time.
Your application must have an login view to input some credentials (e.g. username/email and password).
Steps:
First time the user inputs the correct credentials and successfully authenticates with the server: hash the credentials. For example: var myHash = md5(loginField.getUser() + loginField.getPassword()). You can find md5 JavaScript libraries on Github.
Use that hash to initialize the store. For example: WL.JSONStore.init(..., {password: myHash}).
Send the hash to the backend over HTTPS, you will need it if the user changes his/her credentials. No need to save the credentials or the hash on the device (loginField = null; myHash = null). Alternatively, you could just generate the hash on the server and store it, without having the client send it back, just make sure both client and server are using the same hashing algorithm.
When working offline, ask the user for his/her credentials, hash them and use it to access data inside the store.
If the user changes his/her credentials (e.g. via the web interface for your application), the hash will be different and store won't init. However, the user should've successfully authenticated with the server with the new/valid credentials. Ask the server for the old hash, init the store with the old hash, and change the password to init the store to the new hash based on the new/valid credentials. For example: WL.JSONStore.changePassword(oldHash, newHash).
Optional: You may want to consider using a salt. For example: var salt = Math.random(), myHash = md5(loginField.getUser() + loginField.getPassword() + salt).
You will need to store the salt somewhere so you can re-generate the hash once the user returns to the application. You should be able to init another unencrypted store to persist it. For example WL.JSONStore.init(..., {username: 'metadata'}).then(function(){/*add salt to store*/}). More information regarding using two stores here.
I use the KeyChain to store user's username and password. But I want to store my application's username and password to access my web service. How can I store this securely?
There is no such thing as "some sort of key that only allows your app to access your web service." This is not a solvable problem. It is always going to be possible for clients other than yours (or modified versions of yours) to connect to your web service if used by an authorized user. You must account for this on the server side.
If your point is that you want to provide some thin layer of obfuscation to prevent trivial access to your service, then you would put the credential in your code. You definitely don't want to put it in Keychain, since that is per-device, and you want per-application. I would recommend a long, random string of bytes.