This may be somewhat of a faugue description of my question, and I am unsure if this is best to be posted on Stackoverflow or on Super User.
My problem is the following, I am in planning stage of building an quiz ios-app. In some cases it would actually hand out physical prizes monthly, which means security must be tight enough to decrease cheating possibilities.
I will build a backend in PHP, on a debian server with Apache and a certified SSL (Rapid-SSL).
My guess is that for every question, it needs to send it back and forth to the server for the server to authenticate the answer, and let the user know if the answer was correct or not. For some cases (the non-price-winning quizzes) I even want to return the correct answer.
My question is, what is the best way of doing this, security wise? Should I encode the data that is being send back and forth, and if so... how and with what (is there some common encoding type which I can use, such as base64 or similar)?
Edit
What I meant was encoding, rather then encryption. I updated the question
Also, for authentication I was thinking of using Facebook OAuth login.
Let me explain this in detail:
a) If you are afraid of a man in the middle attack or modification of your packet before sending to server (or receiving data from server), SSL would stop them.
b) If you want to stop hackers/debuggers/reversers, if they reverse your code and your code submits for example high score in SSL, they can also submit it easily, like this:
https://yoursite.com/submithighscore.php?score=[SCORE]
even you are using https, when hacker revealed the URL, score submission method and HTTP parameters, they can also submit fake results using a simple curl command.
So in this case, you can implement an advanced encryption algorithm, like encrypting data using a known algortihm with some your application specific changes, secure your application from reversing (which is hard a little). It will stop most of hackers/reversers.
If you choose a good key-exchange algorithm and encryption schema, faking it for hackers would be hard, except injecting code or modifying your code. This time you have to take all anti-reversing measures. Even if you use a public-key encryption here without taking anti-reversing measures, hacker could inject a code in your application which will add for example X points to every submission of point, it will not take more than a single assembly instruction.
Anyway, it's hard to have a really really secure system, reversers gone reverse, code-breakers gone try to find out your encryption algorithm and try to break it. But you can also do your best to stop most of hackers.
If you are sending over SSL, the data definitely is already encrypted. Thinking about it, the biggest worry is authentication. Knowing for sure that the user that is submitting a question, is actually that user. For that, I would use simple password authentication. And because everything is over SSL, that should be enough. The biggest worry in that case is malware on the user end.
Related
Say I have a PHP application and want the users data to be encrypted before it it gets to the server (to prove to users that their data will not be data mined or resold for advertising).
Similar question was asked here ( Secure Javascript encryption library? ) and implies that this is not going to work, but with the increase in privacy interest amonsgt users this requirement is only going to get greater over time.
Example, using the Stanford library (http://crypto.stanford.edu/sjcl/) a web form has an additional ‘long’ password field which the user pastes in (probably from email for example)
sjcl.encrypt(txtPassword, txtFormFieldToBeEncrypted)
The encrypted data is sent to the PHP page, and the process is reversed when the page is loaded.
Would this work if the users used Chrome or another browser that remembers form values - obviously this is not a secure result, but would this be effective enough to keep the users information private from the host server?
EDIT: Just to be clear, I am only interested in making the information invisible to the host server, and understand that this solution wont protect from 3rd party attacks
Protection on the page is useless, for the simple fact that the encryption key / mechanism will also be in the scope of the page and can thus be tampered with by a malicious party (or by the user itself when inspecting the page).
To avoid data going over the line unencrypted there is also no reason to "roll your own"(tm), because for that there is SSL.
If you want to make sure that the data that you receive on the server was actually originating from a page that you control, you can rely on CSRF protection.
First of all use SSL it is for an only way for secure communication. If you make encryption in JavaScript it is trivial to decrypt your message (because all your code with keys is public).
If you worry about CFRS attack use anti-forgery token (more here: http://bkcore.com/blog/code/nocsrf-php-class.html)
It's perfectly possible to do this, Lastpass for instance built their business model on it. All their server does is store an encrypted blob which they cannot do anything with, all encryption and decryption happens on the client; including a Javascript implementation in the browser. The entire blob of encrypted data is downloaded into the client, where the user's password decrypts it; and in reverse on the way back up to the server.
So if your question is whether it's possible: absolutely. It's also a lot of work, since you will need to be providing the same en-/decryption code for as many platforms as you want to support. You'll also need to secure every context where that code will run, to prevent third parties from injecting code which would allow them to access the client side decrypted data. So, everything needs to go over SSL with no 3rd party content being allowed to be injected.
Here are a bunch of reasons why javascript encryption in the browser is almost always a bad idea.
You need to think deeply about your trust model. Do the users trust the server? If not, there is no hope for trustworthy javascript crypto since the crypto software itself comes from the server. If the users do trust the server, why does the data need to be encrypted client-side? Just use SSL to secure the connection, then have the server encrypt the data before storing it.
I have a application (made in Delphi) that contains a Authentication system (login & password).
This system is in PHP, and the application get results from PHP using HTTP GET method.
The system returns 'OK' if login and password are correct, and 'NO' if not correct.
Like this...
procedure Check;
var
x: string;
begin
x:=Get('www.mywebsite.com/auth.php?user=xxxxxx&pass=zzzzzz');
if x='OK' then
UnlockFeatures
else
MessageBox(0,'You're not VIP','Error',0);
end;
Well, it works fine, but it is very easy to circumvent this system with sniffers, packet editor or proxy.
So, I want to get some information (in PHP) that changes every time, and that could be possible get the same information by my application.
What can I do?
I don't need codes. Just tips, suggestions, please...
Thanks...
Generally i suggest you not to try to outsmart everyone and invent brand new bicycle - you'd 99% fail with some stupid error making your approach completely insecure. There were a lot of precedences like DVD encryption or Win95 security. You'd better try some industry-approved mechanics, that for years been tested for security, that should have readymade implementations for both Delphi and PHP. Few are
TLS (https:// protocol) http://en.wikipedia.org/wiki/Transport_Layer_Security - that would give no protection from MITM attacks, but it sounds exactly what you asked and would require least possible change.
You may try implementing SSO via integrated windows authentication if you server would support that
You may try setting up OpenID or OAuth environments. Generally their v.1 would be simpler than v.2
You may try to bail out of HTTP and use XMPP/Jabber authentication - they take security seriously and libraries for PHP and Delphi exist. Though it should not be much more secure than just using TLS, you may hope that dumb attackers would not be prepared for non-HTTP protocols (there is not internet outside Facebook and such).
You may use Bluetooth-like approach to make special connection("handshake") once (when both client and servers are controlled) just to make special "tokens" interchanged and stored. That is a generic trait to use "controlled environment" to make 1st connection and use some tokens to prove "we had met before" on later connections using generic challenge/response trait. Those tokens should be unique for each client-user-server combinations! If you'd make one server-global clients-shared set of tokens - they would just be easily copied form one client to another and no more security remains.
Those may be coefficients for some not most trivial RNG. constructed be server and saved by both client and server. Then server "challenges" with RNG seed and client should response with proper random value, prooving he knows coefficients.
Those may be some asymmetric crypto, where token is some random "message", then server sends client encruyption keys and expects the correct message encrypted by them, or the token is the password and server generates random text and expects it's correct crypto digital signature to be passed back. You may find encyption libraries at Torry.net for examples. Lockbox3 and Spring4Delphi are among most tested and noted crypto libraries for Delphi implementing some encrypting standards.
Consider you priorities and make your choice.
Would you be able to switch all the authentication layer in one key turn later, having absolutely no care for backward compatibility with non-updated clients, then you might choose the most simple one and only enhance it later if needed. If your users are lazy at upgrades then you'd better choose most secure approach from starters, since you would have no practical way to disable insecure implementation later.
I'm not familiar with Delphi (looooooong time ago...), but as far as the php and security is concerned:
I would use post instead of get (and https if possible)
If you can read php sessions with Delphi, you could add a session variable with a random number and add that as a hidden form field, send it in and check it against the session variable.
I'm developing a website where people will be able to register and access different data via Ajax (powered by jQuery). This is all simple and i shall have no problems doing. the issue is that the data showed by Ajax needs to be secure and not available to be parsed through remote scripts. I can encrypted the data through a AES (in PHP) and decrypt successfully in javascript, but the javascript code will always be visible to everyone (after login). I can use an obfuscator and javascript encryption, but both ways, even mixed, are not secure enough and decryptable. I would prefer avoiding SSL connections, since I am trying to prevent registered users from accessing the information and the SSL connection would only prevent unregistered users from accessing the data.
Registered users will be able to earn money therefore very interested in cheating the code, this is why it has to be bulletproof.
Unfortunately the system needs definitely Ajax (the whole working principle needs to be based on Ajax). The ideal solution would be a way to save the encryption key on a place that can be saved by php and accessed by javascript, but not by users, remote script parsers etc.
Does anyone know a way to create a secure Ajax connection for this purpose?
I really appreciate all your help.
You want something that browsers do not do.
You've asked for: "The ideal solution would be a way to save the encryption key on a place that can be saved by php and accessed by javascript, but not by users, remote script parsers etc."
The design of the web browser and javascript engine in the browser is such that any Javascript that the web browser can execute can be seen by a human who wants to look at it, steal it, borrow it, whatever. Period. There is NO such place that can be accessed by Javascript, but not by users or remote script parsers. You will have to rethink how your app works if this is a problem. Most likely, you need to keep the secret stuff on the server and do more work on the server and less work on the client in order to protect what you want to protect. If you think about it, a browser is just a remote script parser so if you prevent remote script parsing, you prevent a browser. If you allow a browser, you allow a remote script parser.
You can obfuscate your Javascript to your heart's content if you want. That will make it a little more work for a human to understand and do something useful with it, but it will only be an additional obstacle that any determined and competent person can defeat if they really want to. If this secrecy is really important to you, then you need to rethink the design of the app so that secret information is not required in the browser and the browser just works as a display and interaction engine.
Just so I'm clear here. Any code that can be executed by a browser must, by definition, be something that any user or any tool can download and inspect. You can use SSL to protect data from snoopers in transport, but it ultimately has to be readable as Javascript for the browser to be able to execute it.
You can't do exactly what you want. It's like a cheat-proof game design. You CAN make it HARDER, even MORE hard, but NOT 100% secure. You've got to solve the problem froma different approach, like, whatever that is, examine the actions at server-side (e.g. in a stateful manner) and try to detect any non-human behavior. But it's only a matter of someone creating a realistic bot that mimicks the behavior of humans. Encryption is used for preventing 3rd parties -- other than the server and the client -- from eavesdropping/capturing data, NOT for the client. I'm not saying give up on the whole thing, but try a different approach to secure the system. I want to help more, but don't know what exactly you are trying to achieve.
authentication is the only ways to do it.
Just get your users to authenticate (login) and send them the random seed and salt you've used to encrypt their data.
Without the seed/salt, even though a malicious user can decrypt your data it will still be garbage.
If you want javascript to use a piece of data then clients use that data.
If you don't want data to be re-used set up a server-side system where each chunk of data is only valid once.
Proper authentication should solve all these problems.
I want the users to be able to see the data only when Ajax displays them
Then load the data when ajax get's it and not before. Or only partially load data and off-load any sensitive work to the server.
i think the best practice is to make your code (production code) too mush complex to read and edit
you should rename all your variable with letters [a-z] you should not declare ny function always use function(){} inside of another to make it more logical complex this way
the client can still see the code but has nothing to do with it
EDIT: I realize now it's a terrible advice
I'm working on what aims to be a secure method of user registration and authentication using php and javascript but not ssl/tls.
I realise this may well be considered an impossible task that's been tried 1000 times before but I'm going to give it a go anyway. Every example I see online that claims to do it seems to have some huge fatal flaw!
Anyway, my current problem is verifying javascript at the client. The problem being that if my sha1 implementation in javascript is modified by some man-in-the-middle it's not secure at all. If I could just verify that the received javascript has not been tampered with then I think I can pull this off.
The real problem though, is that the only way to do things on the client side is javascript. Simple: write a javascript to verify the integrity of the other javascript files. Nope! Man-in-the-middle can just modify this file too.
Is there a way around this?
To secure your JavaScript, you must examine it in an guaranteed untampered environment. Since you can't create such an environment in the browser this is not possible. Your best option is to download the JavaScript via HTTPS. That isn't safe but better. Possible attack vectors left:
A virus can modify the browser to load some malicious JavaScript for every page
A keylogger can monitor what the user is typing
A proxy can act as a man-in-the-middle for an HTTPS connection. The proxy will actually decode what you send via HTTPS and encode it again (with a different certificate) for the browser.
A proxy can add iframes to the pages you send
Matt
I believe (despite the naysayers) that what you're asking is not impossible, merely extremely difficult. What you're asking is that code that is completely accessible to abuse nevertheless permits the user to identify herself to the server, and vice versa. One possible way is to use a zero-knowledge proof, which will leak no information to the eavesdropper (Eve). For example, the server might provide javascript that draws a representation of a graph that combines user provided information of no value to Eve on its own with server-provided information also of no value. The javascript may have been modified, but will either fail to provide the correct graph (at which point the user WALKS AWAY) or succeed. In the latter case, the user similarly provides 'zero-knowledge' evidence that they have an isomporphic representation of the graph; again, this either succeeds or fails. Also look at the SRP protocol, but the problem with this is that it's a patent minefield. See Practical Cryptography by Ferguson and Schneier. Jo
There's no way around it. As you said: if you cannot verify the source a man-in-the-middle attacker can replace anything the client receives, i.e. anything the client interprets and executes.
You say your only issue is a man in the middle modifying the javascript you use to perform a SHA1. I therefore guess you are using username + SHA1 of password for login....
That is completely insecure even with no Javascript tampering. Even though a man in the middle may not know the plain password if the javascript is not modified, he will know the hash, and he can perfectly use that hash to perform a login on his own by just replaying it.
Even if you include a salt / nonce, the man in the middle could still be able to use those tokens at the moment, and even steal the account by performing a password / email change.
Even ignoring this, and assuming you could actualy get around all that + actually get a javascript to test the integrity of a second javascript, how would you prevent that "verification script" from being tampered too? You keep depending on a script sent over an unsecure channel to assure security on such data (and could recursively go on for ever having a script that checks the integrity of a script that checks the integrity of a script...) all being perfectly tampered since they are sent over an unsecure channel.
The only way to do this would be to be able to build yourself a secure channel on top of http, which would need some client-side extras (a Firefox plugin / an ActiveX extension), but having native support for https that's just absurd.
as they are in the client you cannot access them.
This is the nature of the web pages...
try using important things in server side...
If your security architecture somehow requires functions to run in Javascript, then your security is flawed.
with JavaScript one can protect from passive network attacks (such as eavesdropping WiFi traffic), but you cannot protect yourself from active network attacks where the intruder is capable of controlling your HTTP response header and body data.
If you don't want to pay for the SSL certificate, you can create a self-signed certificate instead. However, this will only prevent passive network attacks, but is a lot easier than some hacky JavaScript implementations you ever create.
Essentially you need a CA signed SSL certificate to prevent active network attacks (a man in the middle).
You can only verify the integrity of Javascript files at the client if, and only if, server and client previously share a secret. That is most often not the case on the Internet. If such a secret is not available, then any attempt to verify transferred Javascript can be broken. It is a catch 22 situation.
Most often, people want to ensure JS integrity because it makes them feel like they can delegate security checks on the client side. In cryptography, there is a fundamental rule that should not be broken: never trust remote user input. Always double-check.
SSL/TLS can make middle-man attacks harder to achieve, but it is not watertight.
I'm trying to make a "normal" username/password login form secure, without needing HTTPS. My idea is this:
Server generates a keypair for some kind of assymetric encryption algorithm. It stores this keypair in a temporary table of sorts (or perhaps the local session data).
Server sends the form to the client and includes the public key.
User fills in the form.
Before it's sent to the server, Javascript encrypts the password using the given public key.
Form is sent.
Server decrypts the password with it's private key (which it gets from the temporary table, using the public key to find it).
What I need to know for this is:
Which encryption method is the best to use? RSA?
How can I decrypt the password in PHP?
And probably the most difficult one, how can I make Javascript encrypt the password?
In advance: I'm sorry for being negative, however;
Implementing your own security protocol is never a good idea, unless you're a highly trained security expert, or you actually don't really care about the security and only want to create an impression of security (marketing) and stop the script kiddies.
SSL is definitely not a fingerprint lock, as so say in your comments, JCryption and your proposal are equal to having a door where you can enter a two-digit code to open the door and you have infinite many retries. It's hard to break if you're not really interested and just passing by, but if you want to get in that house (and you probably do, else security wouldn't be needed), you will get in.
Another point is that people often forget to mention what they want to achieve. Security has the famous three components called CIA, namely confidentiality, integrity and availability. Is it for you important that the data you transport is confidential, or is integrity important (i.e. you're sure that the sent data comes from the one you expect and not the man in the middle)?
To make it concrete in this case, the only thing that you achieve here is that a passive attacker cannot see whats passing by on the line. As soon as your attacker gets active and changes the messages on their route, your whole security falls apart. So my advice would be to just stick with the solution the experts have come up with (TLS in this case, not ssl since that is the old version of it) and just make sure your server supports it.
edit:
Btw, SSL/TLS cannot work without certificates. The whole point in public key crypto is that there should be at least somewhere some trusted party.
On the other hand, if you don't care that your users will get an "invalid certificate" message, you can just create your own certificate which is really easy. In that case your certificate isn't trusted by the browsers, however, you can be sure that at least your communication is safe (okay, there are exceptions in this case, but still ...)
The argument that certificates should be for free is really from a perspective point of view. I think people who claim it is bogus/idiotic don't know what it takes to be a certification authority. These companies invest millions in order to keep the communication secure, and sure they make nice money out of selling certificates, but hey its their job and they also deserve to make money, just like any others.
edit2: after comments
I indeed say that you have a secure communication. However, you miss the point that with self signed certificates you dont know to whom you talk securely. Imagine a dark room which is completely isolated from eavesdropping a conversation. Now imagine the difference between such a room with and without light. If the room has light, you can actually see to whom you're talking securely and only choose to talk to people you like to trust. Now imagine doing the same in a completely dark room. You can only hope that the guy you talk to inside this dark room is just an ally and not your adversary. However, you cannot know that, just hope that it's ok. And although your conversation itself is secure, nobody can listen in, you still dont have "full" security.
If I, being a crook, do a man-in-the-middle attack, I can create a self signed certificate without the user noticing. So the advantage of using TLS with self signed certificates is that you have at least the implementation of the protocol corrent (and even implementing this is far from easy). Moreover you can avoid the ugly warnings by advising your users to manually trust the certificate once. However, this is only possible if you have a relatively small group of returning visitors, for a public website this is not really a solution.
This doesn't seem that secure from the perspective of the client. Two (related) problems:
How does the client trust the server? How can it verify that the key the sever's presenting is the one that belongs to it?
It's possible to do man-in-the-middle attacks. A malicious proxy could strip out and store the public key before the client sees it, substituting its own, then decrypt the password when the client authenticates, store it, and re-encrypt and send the response on so the client doesn't realise something's up.
What's wrong with ordinary SSL? There has to be a consensus that it's secure, otherwise vendors and organisations would drop support for it overnight. By contrast, most attempts to invent a funky new way to do security "on the cheap" usually miss something fundamental.
It looks like a lot of what you want to do is supplied by the jquery plugin JCryption. It even assumes PHP as the backend, so a good fit for you.
Livejournal does something similar to what you want where:
Server generates a challenge string, inserts this into form. [1]
Client generates response by MD5 hashing the password, then MD5 hashing the previous hash with the challenge prepended [2].
Server gets response, checks challenge validity, then does same as step 2, comparing the result to the response.
This is a very good idea, and it's already been done. See jCryption.
jCryption looks interesting, I've not seen it before.
But I have to ask what is wrong with SSL?
Encryption code is notoriously hard to do right, and you can bet that the SSL implementations found in browsers and http servers are much more rigorously tested and reviewed than the jCryption stuff.
That said, jCryption looks neat if you absolutely need to avoid SSL, and you're not dealing with super-sensitive information.
By storing the passwords in encrypted method on the server the server can retrieve the passwords and verify checksum sent by client. Send a session password and ask client to make a hash of session password and the user inputted password, do the same on the server and compare the two hashes.
This will not secure users from MITM attacks - local admins, NSA, telecom, router hijacks, but it will keep the password safe in open wlan.