How to encrypt data in browser with JavaScript and decrypt on server side with PHP

Client-server encryption-decryption using Advanced Encryption Algorithm (AES) in client and server is complicated because exactly the same algorithm must be implemented twice: once for client side in JavaScript and once for server side in PHP,C# etc.


AES is a symmetric block cipher for encrypting texts which can be decrypted with the original encryption key. In an addition to a cipher key it is recommended to use an initialisation vector. It is a fixed-size input for the cryptographic algorithm that is used for encryption and must be known for decryption.

Initialization vector is not a secret. Once it was generated on the crypt side (either client or server) it must be anyhow transferred to the decryption side. The easiest way to send vector to the decryption side is together with cipher. Just add it to cipher and then encode the result with base64 to prepare to transfer through HTTP link.
Note that server must know that received cipher is encoded with base64 and a part of it is an initialization vector.

The typical scenario:
There is data on the client side (some input from user, a password) that will be encrypted by JavaScript and then send to server side with HTTP request where it will be decrypted.

Components
We need 3 components to encrypt-decrypt successfully:
1. cipher – will be generated by JavaScript and send to the server
2. initialization vector – will be generated by JavaScript and send to the server together with cipher
3. key – must be available for both client and server

There are 3 things that we should take care about to encrypt-decrypt successfully:
1. Algorithm must be the same
2. Server must know how the cipher is encoded
3. Server must know how to get initialisation vector part from received cipher

Algorithm pair
The problem is to found a compatible combination of JavaScript and server side algorithms.
PHP has two groups of functions for encryption: mcrypt and OpenSSL. Each group can use different encryption algorithms. I tried lots of different combinations (including crypto-js library and different JS-implementations of mcrypt) until I finally come to the solution. The problem is that most of the libraries do not document how cipher is combined with vector. And how this combination is encoded (uue, base64, utf etc.). Thus it can be decrypted with the same library but it is absolutely no way to decrypt it even using the same algorithm in another library.

After lots of experiments I found a workable pair: GibberishAES JavaScript library on the client side with a custom PHP class uses php openssl extension on the server. It is known how GibberishAES encodes combination of cipher and initialisation vector thus we can decrypt it in PHP.
Here is my simple Gibberish PHP class. It is based on initial code proposed by nbari at dalmp dot com http://www.php.net/manual/en/function.openssl-decrypt.php#107210

Both base64 encoding/decoding and initialisation vector is already included in this class. Thus it is very simple to use it:

All ciphers this library produces begins with the same combination:   U2FsdGVkX1
This is string “Salted__” encoded with base64. All ciphers created by GibebrishAES starts with this string. Do not worry about it.

Unit test

After all I found another JavaScript/PHP combination AES-library, created by one developer, so it should work. But I did not test it.

P.S. Why do we need to encrypt a password and send it to the server and decrypt there instead of just send a hash? Sometimes it is needed because system authenticates users somewhere in a third-party system. In an Active Directory for instance. And a clear password is needed for authentication.

P.P.S. Note! Whatever hash- or encryption- algorithm you use always transfer sensitive data through HTTPS!