Perfect way to encrypt & decrypt password, files in PHP? Perfect way to encrypt & decrypt password, files in PHP? codeigniter codeigniter

Perfect way to encrypt & decrypt password, files in PHP?


Bear in mind that, in order to crack passwords, a hacker would have to have access to the encrypted passwords in the first place. In order to do that they would have to compromise the server's security, which should be impossible if the site is coded correctly (proper escaping or prepared statements).

One of the strongest yet simplest forms of encryption is XOR, however it is entirely dependent on the key. If the key is the same length as the encoded text, then it is completely unbreakable without that key. Even having the key half the length of the text is extremely unlikely to be broken.

In the end, though, whatever method you choose is secured by your FTP/SSH/whatever password that allows you to access the server's files. If your own password is compromised, a hacker can see everything.


Checkout this well documented article A reversible password encryption routine for PHP, intended for those PHP developers who want a password encryption routine that is reversible.

Even though this class is intended for password encryption, you can use it for encryption/decryption of any text.

function encryption_class() {    $this->errors = array();    // Each of these two strings must contain the same characters, but in a different order.    // Use only printable characters from the ASCII table.    // Do not use single quote, double quote or backslash as these have special meanings in PHP.    // Each character can only appear once in each string.    $this->scramble1 = '! #$%&()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~';    $this->scramble2 = 'f^jAE]okIOzU[2&q1{3`h5w_794p@6s8?BgP>dFV=m D<TcS%Ze|r:lGK/uCy.Jx)HiQ!#$~(;Lt-R}Ma,NvW+Ynb*0X';    if (strlen($this->scramble1) <> strlen($this->scramble2)) {        trigger_error('** SCRAMBLE1 is not same length as SCRAMBLE2 **', E_USER_ERROR);    } // if    $this->adj = 1.75;  // this value is added to the rolling fudgefactors    $this->mod = 3;     // if divisible by this the adjustment is made negative}

Caution:

If you are using PHP version >= 5.3.3, then you have to change the class name from encryption_class to __construct

Reason:

As of PHP 5.3.3, methods with the same name as the last element of a namespaced class name will no longer be treated as constructor.

Usage:

$crypt = new encryption_class();$crypt->setAdjustment(1.75); // 1st adjustment value (optional)$crypt->setModulus(3); // 2nd adjustment value (optional)/** *  * @param string $key - Your encryption key * @param string $sourceText - The source text to be encrypted * @param integer $encLen - positive integer indicating the minimum length of encrypted text * @return string - encrypted text */$encrypt_result = $crypt->encrypt($key, $sourceText, $encLen);/** *  * @param string $key - Your encryption key (same used for encryption) * @param string $encrypt_result - The text to be decrypted * @return string - decrypted text */$decrypt_result = $crypt->decrypt($key, $encrypt_result);

Update:

Above class is not intended for encrypting files, but you can!!!

  1. base64_encode your source text (file contents)
  2. for actual encryption, apply above enc/dec class over base64-encoded text
  3. for decryption, apply above enc/dec class over actually encrypted text
  4. base64_decode will give you the actual file contents (you can save a copy of file with this content)

I've encrypted an image, decrypted back and saved to a new file!!! checkout the code.

//class for encrypt/decrypt routines require 'class.encryption.php';//configuring your security levels$key = 'This is my secret key; with symbols (@$^*&<?>/!#_+), cool eh?!!! :)';$adjustment = 1.75;$modulus = 2;//customizing$sourceFileName = 'source-image.png';$destFileName = 'dest-image.png';$minSpecifiedLength = 512;//base64 encoding file contents, to get all characters in our range//binary too!!!$sourceText = base64_encode(file_get_contents($sourceFileName));$crypt = new encryption_class();$crypt->setAdjustment($adjustment); //optional$crypt->setModulus($modulus); //optional//encrypted text$encrypt_result = $crypt->encrypt($key, $sourceText, $minSpecifiedLength);//receive initial file contents after decryption$decrypt_result = base64_decode($crypt->decrypt($key, $encrypt_result));//save as new file!!!file_put_contents($destFileName, $decrypt_result);


Your question leads to two different answers. It's an important difference, whether you need to decrypt the data later (like files), or if you can use a one way hash (for passwords).

One-Way-Hash

If you do not need to decrypt your data (passwords), you should use a hash function. This is safer, because even if an attacker has control over your server and your database, he should not be able to retrieve the original password. Since users often use their password for several websites, at least he doesn't gain access to other sites as well.

As you already stated, one of the most recommended hash functions today, is bcrypt. Despite it's origin in the blowfish algorithm, it is in fact a hash function (not encryption). Bcrypt was designed especially to hash passwords, and is therefore slow (needs computing time). It's recommended to use a well established library like phpass, and if you want to understand how to implement it, you can read this article, where i tried to explain the most important points.

Encryption

If you need to decrypt your data later (files), you cannot prevent, that an attacker with control over your server, can decrypt the files as well (after all the server has to be able to decrypt it). All adds up to the question of where to store the secret key. The only thing you can do, is to make it harder to get the key.

That means, if you store the key in a file, it should be outside the http root directory, so it can on no account be accessed from the internet. You could store it on a different server, so the attacker would need control over both servers, though then you face the problem of the secure communication between the servers. In every case, you can make theft harder, but you cannot prevent it completely.

Depending on your scenario, you could encrypt the files locally on your computer, and only store the encrypted files on the server. The server would not be able to decrypt the files on it's own then, so they are safe.