I need to encrypt a string at client side and send it to the server.
Once there I need to decrypt it.
Is the Using Password-Based Encryption the best solution?
I need it because I have a voting mechanism, where I send ajax posts to vote an entry.
This mechanism use the Facebook id from the current user. My goal is to encrypt the FB id from client side to avoid that they hack it by sending requests with differents ids.
If a second post with the same id is sent I will block the vote.
Once the id is decrypted I will check if it is a real FB user using the graph.
Javascript encryption won't help here. Any good detective/hacker can see how it's all done on the client and see what the data was before it was encrypted and see how it's encrypted.
The only way to prevent a user from voting multiple times is to have the vote tied to an account or token that you can both verify on your server and tie to a particular user that isn't easy for the user to make lots of different accounts. In general, you probably can't stop this entirely, but you can make it enough trouble that most won't do it by making it require enough steps (including some sort of captcha so it can't be automated).
SSL will protect client/server communications, but won't do anything to stop the client from doing things you don't want them to do.
“Encryption” does not make any sense here as you have already been told (because the value that would be encrypted client-side could be manipulated before you encrypt it), and SSL does of course not solve this problem either.
Send the access token of the user to the server instead. And then either make a request for user data with it (/me), or debug it – then you will know that the request is genuine, because a user can not “fake” an access token for another user.
Considering that there is no authentication an HTTP fingerprint can be used to check if requests with different userId come from the same user.
Fingerprint will be create from HTTP request data like:
-user agent
-language
-IP
-charset
and other data present in the http request.
Related
I am writing a JAVA REST webservice, I'm trying to understand how it all works, but I've managed to make simple methods where my client will send a JSON with information, and the server does something with it. Very easy.
So what I am doing: My client wants to create a new object, for example, an account, yet I don't want everyone on the world to simply send a json to my website and create an object.
However I don't want to filter on IP's, because I got no clue who or what will use my client application.
So what have I done to prevent everyone to simply send data? I've created a secret key for the players and they use it like:
http://[website]/[Applicationname]/Webresources/[SECRETKEY]/create
(Send a json with the request)
This works, since now only people with the secretkey can create, and they will only get a secret key if I give it to them. I am pretty sure they won't be giving this secret key to others, since if they do so, they only screw themselves, their services will get loads of fake data...
Yet I want it to be more secure, so noone can obtain the key no matter what, and I don't know if HTTPS will also hide the domain + parameters, I think not, right?
So my question is: how can I send a secret key, without anyone EVER finding out what the secret key is?
Using HTTPS, send POST requests for which you specify your secret key data in the body. You should specify the Content Type to be "x-www-form-urlencoded". The content should be encoded, and adversaries who intercept the url will not be able to decipher the body.
However, your implementation is pretty insecure for sending each request by using the secret key in the URL path, as any adversary intercepting the REST call will know the secret key just by looking at the url. It's way harder and longer to implement but if you can do a Basic Auth or OAuth authorization service, it will authorize only specific users with valid tokens issued to them to access the service, which is the general way of securing your REST services.
First time doing a secure login from a mobile app to a server (built in java). I want to understand if I got this right.
Login in for the first time:
1. On the mobile device hardcode a security phrase (ex: "superSecurePhrase##!!".
2. Take in a username and password.
3. Use base64 to encode username+phrase and password+phrase.
4. Using https send this information to my server.
5. On the server decode using base64 with the matching phrase hardcoded on the device.
6. Hash password and save to DB, also hash username and save to DB.
7. Use AES algorithm to create a session token
8. Send session token to device.
9. Save session token to DB, and when user requests something, make sure they match.
To verify credentials it is pretty much the same process except username and password aren't saved, but instead queried for the DB and checked for a match?
Is this the general pattern used for this kind of thing?
Potential vulnerabilities:
1. Physical access to the device to retrieve the hard coded base64 phrase?
2. SSL Sniffing and acquiring the token?
Thank you for your help.
If I were on your place I would hash the password with SHA-1/SHA-2 on the device when registering. This way I will be sending only the hash. If the request is intercepted by a man in the middle, even if they decode the Base64 encoded string, they will have only the hash. As an end use I will be terrified if someone has my raw password, because I use it on other places (I know it is a bad practice). You can still Base64 encode the hash with the salt.
You can use your "superSecurePhrase##!!" to salt your password string during the SHA-1/2 encoding, or have a separate salt for this.
The token should be random on every generation (it stays the same until it expires), I would use something like the org.apache.commons.lang.RandomStringUtils, assuming you are using Java on the backend.
On the app side I would store the token in the shared preferences, if the device isn't rooted, it isn't accessible by other apps. If it is, and the user allowed root access to the app, you can't do anything about it. Storing in a databes is also OK, if you are already using a database in the app.
So, to sum it up, the biggest difference is that I would prefer to create the password hash on the device and send only the username and the hash over SSL.
This is an existing system with a login screen, now I expose some services as REST service. I build an authentication-token login system for this Rest(jersey) service. User sends username-password then server returns a token calculated as;
sha1(username+password+currenttime(or any random number))
User will use this token to login the app for further requests. And server keeps a copy of the token in the database with a time stamp and user id, and logins that user if timestamp is valid.
Considering HTTPS will be used, a few questions;
Does everything looks ok in my design? (generation of hash and the way I save in DB) Looks to me the weakest point is I need to send plain username and password over POST request, but since it is HTTPS I guess it will not be a problem.
another thing, for the first request, since it is an existing system I dont have the user passwords in my DB but keep a salted hashed version of them. Which I guess not safe to give all the clients this salted algorithm to send me a hash of their passwords so I compare hashs but not the passwords. does this make sense=
1/2- I'd suggest POSTing the username/password to the server, which can then return the token in the body. Makes most sense to me: you're not actually storing much on the server, so PUT would be wrong, and a query parameter doesn't make sense at all. Headers are supposed to be somewhat consistent across requests, so they don't make sense either. When actually communicating using the token, feel free to use a query parameter or header. Doesn't really matter.
3- I'd pick a slightly longer hashing algorithm (sha256?)
I would typically pass the token in an HTTP header.
Whether you use POST or PUT shouldn't matter.
Something else I would suggest to help prevent replay type attacks would be to include a nonce (ever increasing value) with each POST request. The server would then track the last used nonce and prevent any requests that use a previously used nonce from executing.
i intend to use JSON to implement a client server communication. My goal is for a Java-server to receive data via HTTP-Post from an Iphone-app.
I'm concerned about the fact of how I can be sure, that the data the Java-server receives only come from the Iphone-app? It may be possible that somebody else is catching the Java-Server URL and send rigged data?
Do I have a chance to recognize that? SSL encrypts transferred data only, but doesn’t solve the problem, i think.
kind regards
stormsam
You could send a token that is hardcoded into your application. Everything that comes without this valid toke should be rejected. Or you can use .htaccess and specify a user and password within your app.
You could use public key encryption, with users having their own keys and you keeping track of who are the legitimate users. This is the most reliable scheme I can think of. That, or giving each user a username and password. However, it's probably a lot more trouble than it's worth, and still doesn't protect against users that have registered with you but are still malicious.
Embedding a token in your application and then sending it with requests, as Cyprian suggests, is probably the easiest scheme and would probably work pretty well, but might be relatively easy to reverse engineer.
A somewhat better solution might be to program into your app a function that transforms any given input into an output; then, your server responds to a request by giving the app a piece of data to transform, and checks the result. A client that passes the test gets a session token which allows it to proceed. This does require an extra round-trip for authentication, though. And it's still not immune to being reverse engineered, since all the information needed to do so is stored in the app that's present on the user's machine.
Assuming you can reasonably protect your iOS app from being dissambled, you could use "signed requests" like the Facebook API (and probably others):
You'll need a shared secret on both client and server (e.g. a random string/byte array). The iOS app then hashes all request parameters plus the shared secret and appends the hash as additional request parameter, e.g. myserver.com/ws?item=123&cat=456 becomes myserver.com/ws?item=123&cat=456&hash=1ab53c7845f7a. Upon receiving a request, the server then recomputes the hash from the regular parameters and the shared secret and compares it to the value sig parameter. If both are equal, the request is considered valid (assuming integrity of your iOS app).
An advantage of this method is that it doesn't require additional round trips to fetch any one-time/CSRF-prevention tokens and does not require encrypting requests and responses (as long as you only care about the integrity of requests, not confidentiality).
You might have to take a look at this. It may give you some directions.
I'm writing a web application in Java where at some point user can enter there email address to receive an email. My question is about the verification of this email address (so it's not about the validation!). I'm tagging this question also with google-app-engine, because the application will live there, but I don't think that matters too much.
Anyway, for people who have a google account I use the app engine's User API to verify that address, but for other people I would like to send a verification email, that provides them with an URL. Very standard I would think, but are there also standard ways to generate the URL? Or is just creating a hash of the email address, storing that in a database and putting it as a parameter in the URL sufficient?
I wouldn't use e-mail hash in verification e-mail. That would be to easy to guess and someone could actually try to falsify that.
If I were to implement it, I would add random GUID and store it to the DB for verification. I don't know if it is standard way to do verification or not...
Create a servlet that will check, given a key (say, some random string), whether that key is given out previously. The key needs to be crytopgraphically secure so that it cannot be guessed by an attacker wanting to pose as somebody.
Then, when someone signs up with an email, you send a link containing that key to the address they claim they own. If at some point in the future, the link you send arrives at your sever, you can record that event, and be confident that the email address is a correct one.