I have a username and password in my Java app to call an external API. I would like obfuscate these credentials' strings and not hardcode them in plain text inside source code.
Any tip how I can do that?
If the credentials are in an app on an insecure client device, then there is no way to secure them 100%. The common solution is to avoid storing username/password but instead have the user login once to obtain a token from the (secure) application server. This token is stored on the insecure device as securely as feasible, and refreshed on a regular basis: When the token nearly expires, it is used to authenticate with the server and obtain a new token. In this way, if the token is stolen it will not grant access indefinitely.
Related
I read online and understand how to use the FB connect and how to create an app that uses the fb login. What I want to know is whether it is possible to manipulate the data between the authentication.
So here's what I am confuse about. So we have
FB server
my application
my server.
So when I open my application, my application will ask for fb login and pw, we send those info to FB server. The FB server then give my application a token, then my application will send the token to my server, then my server will verify with FB server? Is this how it works?
If that's the way it works why there's no hacking in FB login, can't people make fake tokens?
By your question , even a set of "fake" credentials for all purposes of you app will be a vaid login ( because the user exists on facebook) . Facebook is essentially authenticating that the person is a valid person. A person cannot make a fake facebook token because it is signed
Facebook uses OAuth 2.0, which is a current standard for open authorization. This is a short description from wikipedia:
OAuth provides client applications a 'secure delegated access' to
server resources on behalf of a resource owner. It specifies a process
for resource owners to authorize third-party access to their server
resources without sharing their credentials. Designed specifically to
work with Hypertext Transfer Protocol (HTTP), OAuth essentially allows
access tokens to be issued to third-party clients by an authorization
server, with the approval of the resource owner, or end-user. The
client then uses the access token to access the protected resources
hosted by the resource server.[1] OAuth is commonly used as a way for
web surfers to log into third party web sites using their Google,
Facebook or Twitter passwords, without worrying about their access
credentials being compromised.
You can read the RFC specification for more details: https://www.rfc-editor.org/rfc/rfc6749
You can also read information about the different integrations: http://oauth.net/2/
You cannot create a fake token. The user receives a token after typing his username and passwords, which means stealing his token is equivalent to stealing his credentials, as the token is randomly generated.
I will explain the flow shortly:
I'm an user, using in general facebook and your application. I log in facebook and reach your application in facebook or via external link and click on it. Then facebook will ask me if I want to share my personal information with your application (this is because I am logged in. If I were not, then it would ask me for my username and password). If I agree, facebook will send an access token to your application and with it you will access of my personal information. Thus this access will be highly restricted and you won't be able to do anything harmful and as well it will expire after a couple of time, depending on the implementation, but should be around one hour.
I am storing the user credentials in a properties file, and use them whenever my java application makes a request to the server, and upon confirmation, the user is redirected to an ASP page. The issue with this approach is, the user credentials are visible in the URL, during the redirection to the ASP page.
How do I encrypt the credentials (at least the password) so that exact information is not displayed in the URL?
You can use MessageDigest SHA encryption to send the data to server. However you need to make changes to your ASP web application to decrypt the credentials. It is not one way street.
For this case sharing login information between different applications, the common solution is to use SSO, for example CAS. User login from java application which will get a valid token from CAS server and you can redirct to ASP page with the token instead of user name and password. Your ASP application needs to configue to use CAS to verify the token.
Keeping the security aspect in mind, consider implementing Salted Password Hashing.
Problem Description
I am writing application which must connect to the server and download some data from the server. The URL of the file witch must be downloaded is formatted as follow:
http://www.myserver.com/file.xml?username=xxx&password=xxx
Question
URL and password are not provided by the user, I simply keep them in the code and add to the URL where I need. My question is how can I keep securely password and username on the Android device.
I would advise against keeping any kind of credential (username) and authenticator (password) stored on your device, as well as transmitting them around; this is often considered a security flaw, since middle-man attacks can intercept the HTTP traffic and easily identify both.
I would recommend instead the creation a token engine that would associate temporary identifiers to users and devices. For example:
User ID 100 receives a temporary token, code A1S2D3F4 (randomly generated.)
The code is associated with the device ID AND200.
Whenever device AND200 tries to access the server, it would generate the following URL:
http://www.myserver.com/file.xml?t=A1S2D3F4
Notice that there is no content identifying the user, nor its credentials or passwords. You may check if the device generating the URL is the one the token was originally associated with. Adittional controls may be implemented to detect tokens being used out of their lifespan, and help identify malicious users.
In Android you can use Md5 encoding method for password encoding and if you need to save those user details then it store in the shared preference
Did you see if you can use Google OAuth2: http://developer.android.com/training/id-auth/authenticate.html
If not, do not send user name and password in the URL but in a HTTPS POST and the correct way is using SOAP web services.
Just as a hint there is a good talk on google io conference about security of android apps.
Link
They don't cover secure server communication explicitly but give some hints about it and provide an encryption library to simplify any encryption tasks.
My company is building a RESTful API that will return moderately sensitive information (i.e. financial information, but not account numbers). I have control over the RESTful API code/server and also am building the Android app. I've setup the API to use OAuth 2 with authorization code grant flow (with client ID and secret), and I auto-approve users without them having to approve the client since we own both client and provider. We use CAS for SSO and I am using this for the Authorization server as part of the OAuth 2 process when the user logs in to retrieve the token.
I am contemplating various ways to secure the data on the Android app. I've concluded that storing the client id and secret on the device is definitely not going to happen, but am thinking that storing the auth token might work, since it is only risk to the individual user (and really only if they happen to have a rooted phone).
Here are two options I have thought of. They both require me to have a sort of proxy server that is CAS protected, does the dance with the API server, and returns the auth token. This gets rid of the need for storing the client id and secret in the app code.
Here are what I've come up with:
1) Require the user to enter their password to access data each time they startup the App. This is definitely the most foolproof method. If this were done, I'd probably want to save the userID for convenience, but in that case couldn't use the CAS login (since it's web-based). I might be able to use a headless browser on the backend to log the user into CAS and retrieve the token based on what they enter in the Android form, but this seems hacky. Saving the userID is similar to what the Chase app does (if you happen to use this one) - it saves the userID but not your password between sessions.
2) Store the auth token on the Android device. This is a little less secure, but almost foolproof. When the user starts the app for the first time, open the webpage to the CAS login of the proxy server that returns the token (similar to https://developers.google.com/accounts/docs/MobileApps). After the user logs in and the token is returned to the app, encrypt it and store it private to the application. Also, use ProGuard to obfuscate the code, making the encryption algorithm more difficult to reverse engineer. I could also work in a token refresh, but I think this would be more of a false sense of security.
3) Don't use CAS but come up with another way to get an auth token for the service.
Any advice of how others have implemented similar scenarios (if it's been done)?
Thanks.
Well the reason why standards like OAuth are developed is that not everyone has to rethink the same attack vectors again and again. So most often it is your best choice to stick to something already available instead of baking your own thing.
The first problem with clients that are not capable of secretly storing data is that the user's data could be accessed by some attacker. As it is technically not possible to prevent this (code obfuscation won't help you against an expert attacker), the access token in OAuth 2 typically expires after short time and doesn't give an attacker full access (bounded by scope). Certainly you shouldn't store any refresh token on such a device.
The second problem is client impersonation. An attacker could steal your client secret and access your API in his own (maybe malicious) app. The user would still have to login there himself. The OAuth draft there requires the server to do everything it can to prevent this, but it is really hard.
The authorization server MUST authenticate the client whenever possible. If the authorization server cannot authenticate the client due to the client's nature, the authorization server MUST require the registration of any redirection URI used for receiving authorization responses, and SHOULD utilize other means to protect resource owners from such potentially malicious clients. For example, the authorization server can engage the resource owner to assist in identifying the client and its origin.
I think Google are the first to try another approach to authenticate a client on such devices, by checking the signature of the application, but they are not yet ready for prime time. If you want more insight into that approach, see my answer here.
For now, your best bet is to stay on the OAuth way, i.e. having the access token, client ID and client secrect (when using the authorization code grant flow) on the device, and configure your server to do additional checks. If you feel more secure obfuscating these, just do it, but always think of it as if these values were publicly available.
Here's the problem: I'm developing a desktop application to interface with a server, and the client has to log in. Something like with Skype or IM applications. I want to give the client the option of being logged in automatically, ie. no need to type in their credentials every time the applications loads.
How can I achieve this, while protecting the client's information?
Thank you, I've been pondering this problem for days now and I can't seem to come up with a solution. Any help or guidance would be gold at this stage.
If you are using a secure communication channel to the server (like using SSL, for instance) then you could send the username and a hash of the password (using a cryptographically secure hash function like SHA-512 - there's no known feasible collision or preimage attacks).
What you save locally is the username and the hash of the password. Given that the communication channel to the server is secure nobody else will see the information sent (no replay attack possible). And using a cryptographically secure hash function means that it's a one-way function, no "going back" to the original input.
Another way would be to get a token of authentication from the server upon successful login. Then the protocol could accept authentication of user combined with the token within a certain duration of time. Then you don't have to store the hash of the password locally, only the username and the token. Thus if somebody gets the token it will expire at some point. But bear in mind that the token should not be reissued using another token, only with a correct username/password combination. Additionally, the user should not be able to change/see the password if logged in using a token either. If you want to go even further then you could also restrict the token to only work from certain IP address(es).