Tell me more ×
Cryptography Stack Exchange is a question and answer site for software developers, mathematicians and others interested in cryptography. It's 100% free, no registration required.

Lets say I have a web page with a form on it. There is javascript to submit the form after doing encryption. The encrypted string from the text box gets sent visibly to the server, which is running PHP, to be decrypted and stored.

What is the most secure encryption algorithm I can use with Javascript and PHP?

Assume the server and the client already have a shared secret encryption key (maybe I carried over the code to my friend on a flash drive) and also assume the attacker can get the source of the page (so they can see the method of encryption) and the encrypted message.

Of course this won't be my final scenario, I simply want to focus on the transit security. I have been thinking about some kind of AES, but I'm not sure about if there is a better algorithm to use.

share|improve this question
What speaks against SSL/TLS? – Ekris Nov 1 '12 at 22:45
This is a hypothetical situation. "Of course this won't be my final scenario" – Stephen Nov 1 '12 at 23:08
if its transit security , why do u want to reinvent the wheel , go with SSL/TLS – sashank Nov 2 '12 at 6:58
First of all: You need https anyway in order to prevent an attacker from manipulating the JavaScript in transit. Otherwise the modified javascript can just send a plain text copy of the data to another server. AES is a good solution, if you want to prevent the webserver from seeing it (e. g. if the webserver is under the control of an American cloud company which is in violation of European privacy law). While this will prevent passive sniffing on the webserver, an active attack by the webserver will modify the JavaScript. – Hendrik Brummermann Nov 2 '12 at 9:53
SSL will only work if the users are trained to make sure the url is https, otherwise it's useless and susceptible to attacks. Also, Hendrik, this is a hypothetical situation, as I have stated and repeated multiple times. I said to only assume the attacker can read the page, not modify it. – Stephen Nov 3 '12 at 19:48

closed as off topic by Antony Vennard, Thomas, Hendrik Brummermann Nov 2 '12 at 9:53

Questions on Cryptography Stack Exchange are expected to relate to cryptography within the scope defined in the FAQ. Consider editing the question or leaving comments for improvement if you believe the question can be reworded to fit within the scope. Read more about closed questions here.

1 Answer

If the attacker can see the source code of the page, they can see the key if it is transmitted over the wire, and your only reasonable option is for the user to be responsible for entering a 256-bit or greater key.

If the attacker can see the live browser DOM, then there is nothing you can do.

I'll assume the first, which is awful from a usability perspective.

Once:

1. Generate a cryptographically random 256-bit key. Somehow share this securely with the user, out of band.

To encrypt:

1. Generate 128 cryptographically random bits on the server, and send them to the client
  1. this will be the IV
2. Encrypt the data with AES-128-CBC using
  1. the *first* 128 bits of the shared key as the key
  2. the received IV
  3. the plaintext
3. Calculate the HMAC-SHA-256 using
  1. the *last* 128 bits of the shared key as the key
  2. the received IV prepended to the ciphertext as the data
4. Transmit the ciphertext, the HMAC, and the IV to the server.

To decrypt:

1. Calculate the HMAC-SHA-256 using
  1. the *last* 128 bits of the shared key as the key
  2. the IV prepended to the ciphertext as the data
2. Compare the calculated HMAC with the received HMAC by
  1. XOR the byte representations of the HMACs
  2. AND all of the bits of the previous result
  3. If the result is 1, abort
  4. If the result is 0, continue
3. Decrypt the data using AES-128-CBC using
  1. the *first* 128 bits of the shared key as the key
  2. the received IV
  3. the received ciphertext

Notes:

* good luck finding a Javascript cryptography library
* JavaScript currently has no access to a CSPRNG, so we generate IVs server-side
* if decryption fails, you *must not* indicate so in any way, e.g.:
  * do not return failure
  * do not perform fewer operations and thus return a response more quickly
share|improve this answer
No you misunderstood me. "Assume the server and the client already have a shared secret encryption key" I have already taken care of key exchange and I phrased it that way because it's not a problem. I only want to focus on security of the encryption method assuming the attacker knows the method and the encrypted message. – Stephen Nov 1 '12 at 22:49
1  
Oh come on. I know how to use google ;) code.google.com/p/crypto-js – Stephen Nov 1 '12 at 23:25
1  
No. Saying "use AES-128" to a question about cryptography is like responding to a question about general programming with "use C" (or Ruby, or whatever). Encryption is not magic fairy dust. It must be used correctly, or it often provides no security at all. To use cryptography correctly is hard. Based on your question, it is not unreasonable to assume you are a novice in the domain and thus extremely unlikely to perform it correctly without guidance. Should you choose to deviate from my advice without understanding why, I can virtually guarantee that you will have critical flaws. – Stephen Touset Nov 1 '12 at 23:30
1  
Mersenne Twister is not a CSPRNG, nor does SHA-256 of the result turn it into one. If you don't have access to a CSPRNG directly, you may want to consider using PBKDF2 with a sufficient number of rounds (128,000+). – Stephen Touset Nov 1 '12 at 23:59
1  
I'm not trying to be hard on you. You asked for "most secure", and I took you at face value on that. Cryptography is hard. – Stephen Touset Nov 2 '12 at 0:15
show 11 more comments

Not the answer you're looking for? Browse other questions tagged or ask your own question.