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

1myb picture 1myb · Aug 20, 2012 · Viewed 26.8k times · Source

I did a series of research on this topic, but unfortunately I couldn't find a perfect way to encrypt and decrypt files in PHP. Which mean what I'm trying to do is find some way to encrypt & decrypt my items without worry of cracker knew my algorithm. If some algorithm that need to secrete & hide, it can't solve my problems while once the logic shared through anywhere, or they broke into my server and get the source file, then it should be some way to decrypt it using the same decryption algorithm. Previously I found several great posts on StackOverFlow website, but it still couldn't answer my question.

The best way to encrypt password of the world, from what I conclude through reading. Blowfish encryption. It's one way hashing algorithm with 1000's times iteration which make cracker need 7 years to decrypt by using the same specification GPU.

Obviously, this makes it impossible to decrypt while it's one-way hashing.

  1. How do you use bcrypt for hashing passwords in PHP?
  2. Why do salts make dictionary attacks 'impossible'?

The best way to encrypt and decrypt password in PHP, as this question quote as it is. Refer to what I found through the web, sha1 and md5 both are cracked & broken algorithm, even we change the algorithm from

$encrypted = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, md5($key), $string, MCRYPT_MODE_CBC, md5(md5($key))));

To

$encrypted = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, sha1(md5($key)), $string, MCRYPT_MODE_CBC, sha1(md5(md5($key)))));

Are not it's just increasing the toughness to decrypt it but still crack-able while just time issue ?

  1. Best way to use PHP to encrypt and decrypt passwords?

I'm thinking of using our server processor / harddisc GUID to generate the salt and encrypt the password.

It's still some stupid way to do while cracker got the access to the server and they can just use PHP to echo the GUID and do the decryption. Or if it works, a few years later my website will be in trouble. The reason is harddisc, processor never last forever. When the time my processor or harddisc down, it's a time when my website down and lost all the credential.

Update

Found this question which doing with blowfish for decryption in PHP. Is it solving the question of finding secured way to encrypt and hard to decrypt by others ?

  1. How to decrypt using Blowfish algorithm in php?

Can anyone please suggest on how should I overcome this issue ? Thanks.

Answer

rajukoyilandy picture rajukoyilandy · Aug 24, 2012

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);