Jumat, 25 November 2016

6 Fungsi enkripsi di PHP untuk kriptografi

 

Enkripsi merupakan proses mengubah teks polos (plain text) menjadi bentuk lain (kode sandi atau hash). Enkripsi bertujuan untuk melindungi informasi rahasia seperti kata sandi atau password. PHP menyediakan beberapa fungsi untuk melakukan enkripsi, diantaranya: password_hash(), crypt(), md5(), hash(), sha1(), dan base64_encode().




1. Fungsi password_hash()

Fungsi ini akan menghasilkan sebuah kode sandi (hash) baru dengan algoritma one-way hashing. Contoh penggunaan:
 
<?php echo password_hash("rosoftsilaen", PASSWORD_DEFAULT); ?>

akan menghasilkan kode acak yang berubah-ubah:

 
$2y$10$/qwgHfQx0eyZ.IZeMPRYceFLFTM7rVpmgfDDMouEwd.p4EeTLZtDi

Sepertinya fungsi ini sangat cocok untuk mengenkripsi password. Karena kode yang dihasilkan selalu berubah. Oleh sebab itu, fungsi ini juga dibantu oleh fungsi password_verify() untuk memverifikasi kode sandi. Contoh penerapan:

<?php
/**
 * LANGKAH 1: PENGGUNA BERGABUNG DI WEB DAN MEMBUAT PASSOWRD
 */
// Bergabung dan membuat password:
$password = 'PasswordsangatRahasia!';
$passwordHash = password_hash($password, PASSWORD_DEFAULT);

// These are the hashed password's components
// password_verify will use this info to recreate the hash created by password_hash()
$algo = substr($passwordHash, 0, 4); // $2y$ == BLOWFISH
$cost = substr($passwordHash, 4, 2);
$salt = substr($passwordHash, 7, 22);

/**
 * STEP 2: USER LOGS INTO SITE
 */
// User now attempts to log in with $password:
// User provides the password in plain text
$plainText = $password;
// Password hash created when user signed up is now retireved from database
$passwordHashFromDatabase = $passwordHash;
// The application will now use password_verify() to recreate the hash and test
// it against the hash in the database.
$result = password_verify($plainText, $passwordHashFromDatabase);
$success = ($result) ? 'True': 'False';

// Output
$info = <<<__INFO__
Plain text password: $password
Hashed password: $passwordHash
Hash components:
    Algo: $algo
    Cost: $cost
    Salt: $salt

Login attempt:
    User returns to log in with password $plainText.
    Password hash retrieved from DB: $passwordHashFromDatabase
    Login result:
        password_verify(
            $plainText,
            $passwordHashFromDatabase
        );

Was login successful? $success.
__INFO__;

echo $info;

if (!defined('PASSWORD_DEFAULT')) {

    define('PASSWORD_BCRYPT', 1);
    define('PASSWORD_DEFAULT', PASSWORD_BCRYPT);

    /**
     * Hash the password using the specified algorithm
     *
     * @param string $password The password to hash
     * @param int    $algo     The algorithm to use (Defined by PASSWORD_* constants)
     * @param array  $options  The options for the algorithm to use
     *
     * @return string|false The hashed password, or false on error.
     */
    function password_hash($password, $algo, array $options = array()) {
        if (!function_exists('crypt')) {
            trigger_error("Crypt must be loaded for password_hash to function", E_USER_WARNING);
            return null;
        }
        if (!is_string($password)) {
            trigger_error("password_hash(): Password must be a string", E_USER_WARNING);
            return null;
        }
        if (!is_int($algo)) {
            trigger_error("password_hash() expects parameter 2 to be long, " . gettype($algo) . " given", E_USER_WARNING);
            return null;
        }
        switch ($algo) {
            case PASSWORD_BCRYPT:
                // Note that this is a C constant, but not exposed to PHP, so we don't define it here.
                $cost = 10;
                if (isset($options['cost'])) {
                    $cost = $options['cost'];
                    if ($cost < 4 || $cost > 31) {
                        trigger_error(sprintf("password_hash(): Invalid bcrypt cost parameter specified: %d", $cost), E_USER_WARNING);
                        return null;
                    }
                }
                // The length of salt to generate
                $raw_salt_len = 16;
                // The length required in the final serialization
                $required_salt_len = 22;
                $hash_format = sprintf("$2y$%02d$", $cost);
                break;
            default:
                trigger_error(sprintf("password_hash(): Unknown password hashing algorithm: %s", $algo), E_USER_WARNING);
                return null;
        }
        if (isset($options['salt'])) {
            switch (gettype($options['salt'])) {
                case 'NULL':
                case 'boolean':
                case 'integer':
                case 'double':
                case 'string':
                    $salt = (string) $options['salt'];
                    break;
                case 'object':
                    if (method_exists($options['salt'], '__tostring')) {
                        $salt = (string) $options['salt'];
                        break;
                    }
                case 'array':
                case 'resource':
                default:
                    trigger_error('password_hash(): Non-string salt parameter supplied', E_USER_WARNING);
                    return null;
            }
            if (strlen($salt) < $required_salt_len) {
                trigger_error(sprintf("password_hash(): Provided salt is too short: %d expecting %d", strlen($salt), $required_salt_len), E_USER_WARNING);
                return null;
            } elseif (0 == preg_match('#^[a-zA-Z0-9./]+$#D', $salt)) {
                $salt = str_replace('+', '.', base64_encode($salt));
            }
        } else {
            $buffer = '';
            $buffer_valid = false;
            if (function_exists('mcrypt_create_iv') && !defined('PHALANGER')) {
                $buffer = mcrypt_create_iv($raw_salt_len, MCRYPT_DEV_URANDOM);
                if ($buffer) {
                    $buffer_valid = true;
                }
            }
            if (!$buffer_valid && function_exists('openssl_random_pseudo_bytes')) {
                $buffer = openssl_random_pseudo_bytes($raw_salt_len);
                if ($buffer) {
                    $buffer_valid = true;
                }
            }
            if (!$buffer_valid && is_readable('/dev/urandom')) {
                $f = fopen('/dev/urandom', 'r');
                $read = strlen($buffer);
                while ($read < $raw_salt_len) {
                    $buffer .= fread($f, $raw_salt_len - $read);
                    $read = strlen($buffer);
                }
                fclose($f);
                if ($read >= $raw_salt_len) {
                    $buffer_valid = true;
                }
            }
            if (!$buffer_valid || strlen($buffer) < $raw_salt_len) {
                $bl = strlen($buffer);
                for ($i = 0; $i < $raw_salt_len; $i++) {
                    if ($i < $bl) {
                        $buffer[$i] = $buffer[$i] ^ chr(mt_rand(0, 255));
                    } else {
                        $buffer .= chr(mt_rand(0, 255));
                    }
                }
            }
            $salt = str_replace('+', '.', base64_encode($buffer));
        }
        $salt = substr($salt, 0, $required_salt_len);

        $hash = $hash_format . $salt;

        $ret = crypt($password, $hash);

        if (!is_string($ret) || strlen($ret) <= 13) {
            return false;
        }

        return $ret;
    }

    /**
     * Get information about the password hash. Returns an array of the information
     * that was used to generate the password hash.
     *
     * array(
     *    'algo' => 1,
     *    'algoName' => 'bcrypt',
     *    'options' => array(
     *        'cost' => 10,
     *    ),
     * )
     *
     * @param string $hash The password hash to extract info from
     *
     * @return array The array of information about the hash.
     */
    function password_get_info($hash) {
        $return = array(
            'algo' => 0,
            'algoName' => 'unknown',
            'options' => array(),
        );
        if (substr($hash, 0, 4) == '$2y$' && strlen($hash) == 60) {
            $return['algo'] = PASSWORD_BCRYPT;
            $return['algoName'] = 'bcrypt';
            list($cost) = sscanf($hash, "$2y$%d$");
            $return['options']['cost'] = $cost;
        }
        return $return;
    }

    /**
     * Determine if the password hash needs to be rehashed according to the options provided
     *
     * If the answer is true, after validating the password using password_verify, rehash it.
     *
     * @param string $hash    The hash to test
     * @param int    $algo    The algorithm used for new password hashes
     * @param array  $options The options array passed to password_hash
     *
     * @return boolean True if the password needs to be rehashed.
     */
    function password_needs_rehash($hash, $algo, array $options = array()) {
        $info = password_get_info($hash);
        if ($info['algo'] != $algo) {
            return true;
        }
        switch ($algo) {
            case PASSWORD_BCRYPT:
                $cost = isset($options['cost']) ? $options['cost'] : 10;
                if ($cost != $info['options']['cost']) {
                    return true;
                }
                break;
        }
        return false;
    }

    /**
     * Verify a password against a hash using a timing attack resistant approach
     *
     * @param string $password The password to verify
     * @param string $hash     The hash to verify against
     *
     * @return boolean If the password matches the hash
     */
    function password_verify($password, $hash) {
        if (!function_exists('crypt')) {
            trigger_error("Crypt must be loaded for password_verify to function", E_USER_WARNING);
            return false;
        }
        $ret = crypt($password, $hash);
        if (!is_string($ret) || strlen($ret) != strlen($hash) || strlen($ret) <= 13) {
            return false;
        }

        $status = 0;
        for ($i = 0; $i < strlen($ret); $i++) {
            $status |= (ord($ret[$i]) ^ ord($hash[$i]));
        }

        return $status === 0;
    }
}
?>
akan menghasilkan :
 Plain text password: PasswordsangatRahasia!
Hashed password: $2y$10$ww/o6pzj9HpqlvthlAUmMO618Q9xxY8agdgnIVzt27mqEdvkKtz7i
Hash components: Algo: $2y$ Cost: 10 Salt: ww/o6pzj9HpqlvthlAUmMO
Login attempt: User returns to log in with password PasswordsangatRahasia!.
Password hash retrieved from DB: $2y$10$ww/o6pzj9HpqlvthlAUmMO618Q9xxY8agdgnIVzt27mqEdvkKtz7i
Login result: password_verify( PasswordsangatRahasia!, $2y$10$ww/o6pzj9HpqlvthlAUmMO618Q9xxY8agdgnIVzt27mqEdvkKtz7i );
Was login successful? True.

2. Fungsi crypt()
Fungsi ini menghasilkan kode sandi yang lebih pendek daripada fungsi password_hash(). Contoh:  
<?php echo crypt("silaentech", "samosir"); ?>

akan menghasilkan:

saR52qego3GSw

Bila diperhatikan, susuan karakter yang dihasilkan mirip seperti karakter yang digunakan di alamat URL video youtube. Mungkin saja youtube juga menggunakan algoritma yang sama dengan fungsi ini.

Pada contoh diatas, fungsi diberikan dua parameter. Parameter pertama adalah teks yang akan dienkripsi. Sementara, parameter kedua adalah salt (samosir). samosir adalah sebuah data acak yang dimasukkan ke dalam fungsi enkripsi.
 
 
3. Fungsi md5()
Fungsi ini menghasilkan kode sandi sepanjang 32 karakter. Contoh:




<?php echo md5("silaentech"); ?>

akan menghasilkan:

86500716d2cb52bb2520adeb0f42eb4c

Bila ditambahkan kata samosir, hasilnya akan berubah. Contoh:

<?php echo md5("silaentech", "samosir"); ?>

akan menghasilkan:

�P  ��R�% �� B�L

4. Fungsi hash()
Fungsi ini akan menciptkan sebuah kode sandi dengan algoritma tertentu. Contoh:

<?php echo hash("md5", "silaenrosoft"); ?>

akan menghasilkan:

70792ad6faedb7a40b983142d21246a8

Pada contoh di atas, parameter "md5" adalah nama algortima yang digunakan. Sementara, "silaenrosoft" adalah teks yang akan dienkripsi.

Bila ingin mengetahui nama-nama algoritma yang bisa dipakai fungsi ini. Silahkan coba contoh kode yang diberikan dari web dokumentasinya:

<?php
$data = "Dainang br Sijabat";

foreach (hash_algos() as $v) {
        $r = hash($v, $data, false);
        printf("%-12s %3d %s\n", $v, strlen($r), $r);
}
?>

maka akan menghasilkan: 
Data hosted with ♥ by Pastebin.com - Download Raw - See Original
md2 32 d7e9264d2a9d7b329bc9a57e6719449e 
md4 32 9edc49370ed790d57419cb0129fcab42 
md5 32 c1a8f06a8e5f7d4245334dead2ec9532 
sha1 40 11f1eaeb7c05663d2fe8737ee6f3b0a71f09d6f8 
sha224 56 9d78e5c2aca74cdd107b2dec1238f2b41d72cf6e1fc4eec8c55f29b7 
sha256 64 9161b5eb20fa4e9f5b304b580ed3e03370feedaf6ffc6074d0c92ba200ef54f0 
sha384 96 a5ce369b284522e330856af2374d3cfda2c74fdf28a101099a8b7470ac81226bcb5a49fa859ffc08f1c1a279d9b35263 
sha512 128 c18cba53c03a02b2ee9239acbbe04894cdff092a4a8410b754c4ac7142d57fc889a940def3087f2ea2670661a3f9c3c08131ae171994507a96d51b500ba55495 
ripemd128 32 e76fff88f69802e33769336c508db5be ripemd160 40 85582d5265e7de6a79b3d348012cd97561e136d0 
ripemd256 64 47d7939541ba34b6b493743f8f240d789d82f92f6a32091fa33b1b05bc1b655d 
ripemd320 80 f3bc7769df8f47888135a89937564e206b3941049b784cbb020225895c2a6746e228ad5ce4c4f551 
whirlpool 128 6536bbe9a5f9ddd0e4fb360248813648eb82ee69461bd2a32c42d696165a33c7fe163c9ae89ba2a056c34ff29ce7f088285f739536623ca27ea9206b232097c8 
tiger128,3 32 236dab238b3a52f1e2533a2d8fb3da2c 
tiger160,3 40 236dab238b3a52f1e2533a2d8fb3da2c34045c1e 
tiger192,3 48 236dab238b3a52f1e2533a2d8fb3da2c34045c1e029ee96d 
tiger128,4 32 8d9301be303cfc5e3fa1544b6a1cd220 
tiger160,4 40 8d9301be303cfc5e3fa1544b6a1cd2200914c8a3 
tiger192,4 48 8d9301be303cfc5e3fa1544b6a1cd2200914c8a358abb39a 
snefru 64 5464e35dab0ea1bcc925dd0a267a00969d81ace0838a2dc592e18dc72f629e2d 
snefru256 64 5464e35dab0ea1bcc925dd0a267a00969d81ace0838a2dc592e18dc72f629e2d 
gost 64 a5a731dec95f2086250589c3793639859a6802b480e4fd773b8f77227b8ee026 
gost-crypto 64 5b109558d5b3bb9feb062ebf4dedf901894d508a9ef0c5c25f04a559f262cff7 
adler32 8 3ce80685 
crc32 8 81194165 
crc32b 8 a9a967bf 
fnv132 8 8c62ac7d 
fnv1a32 8 275553fd 
fnv164 16 0b72528e5b4ffe1d 
fnv1a64 16 e116caeb855cc31d 
joaat 8 ee160956 
haval128,3 32 4b30be7d4f6ef81d53f12c83276a9ef1 
haval160,3 40 d9b5b5618eb1e8c811dbcd63eb0f622718f67995 
haval192,3 48 e28332116d0a013efb2521ea87038f59edb7f84ba3b17e83 
haval224,3 56 1cccfffb3836801353902adc4f8b9d61f7cf24154ccd5a5b9a0e0b57 
haval256,3 64 3ed33928db6cb058fa40e4ad767508e88230dc0cced7235edc6f013231838f1c 
haval128,4 32 c270e8a0d8f323d415cfd5de91693282 
haval160,4 40 a5594ef5e6b0c0e8926ced19fb968f0ddaaade65 
haval192,4 48 bf76c1142308616edfb4aebf84b8a12e7d6698495b5f572f 
haval224,4 56 0a1633be624530e9da975d52b0e00cdad36f946a65e060ef499be364 
haval256,4 64 2e09fc546af919907ac7ae18018758048a7a7d38f417794b948737ccbc6c99a7 
haval128,5 32 c7ca208850f35bbfac76eb5025436d45 
haval160,5 40 edc3fec95ad72a7d2931007177480bdf54a2ed7f 
haval192,5 48 7031d1e334d3402163f761d186c97ded0a6cf3cae81bc3dd 
haval224,5 56 e3f48318fd5047e69b8610f09ab767d6c9aa01831e91c64e4001c561 
haval256,5 64 39bdf011ebeab308c71cc2734934529a441bdefa2c10c767a3332bbda721836b 


5. Fungsi sha1()
Fungsi ini akan menghasilkan kode sandi sepanjang 40 karakter. Mirip seperti fungsi md5(). Contoh:

<?php echo sha1("silaenrosoft"); ?>

akan menghasilkan:

b060bdc5454e94c0deaf7017b858a6860182281b

Seperti halnya fungsi md5(), fungsi ini juga akan menciptakan karakter aneh, bila ditambahkan 76n. Contoh:

<?php echo sha1("rosoft", "76n"); ?>

akan menghasilkan:

i)��� ĵ�ւ*��v�r�

6. Fungsi base64_encode()
Fungsi ini menghasilkan kode sandi dari teks yang diinputkan. Contoh:

<?php echo base64_encode("Rosofti Silaen - Silaentech.blogspot.com"); ?>

akan menghasilkan:

Um9zb2Z0aSBTaWxhZW4gLSBTaWxhZW50ZWNoLmJsb2dzcG90LmNvbQ==

Sementara, untuk dekripsi atau dekode dapat menggunakan fungsi base64_decode(). Contoh:

<?php echo base64_decode("Um9zb2Z0aSBTaWxhZW4gLSBTaWxhZW50ZWNoLmJsb2dzcG90LmNvbQ=="); ?>

akan menghasilkan:

Rosofti Silaen - Silaentech.blogspot.com

Kesimpulan :
Itulah enam fungsi untuk melakukan enkripsi di PHP. Setiap fungsi memiliki algoritmanya masing-masing. Anda juga bisa meracik sendiri fungsi enkripsi dengan memanfaatkan fungsi-fungsi di atas. Penambahan salt (garam) pada fungsi bertujuan agar password atau kode sandi tidak mudah dipecahkan. 

http://php.net/manual/en/refs.crypto.php

Tidak ada komentar:
Write komentar


Follow us on FB

Featured Video

Pencarian..