Implementasi Password Hash dan Password Verify pada PHP

Pada tulisan kali kita akan berbicara mengenai fungsi password_hash() dan password_verify() yang ada pada PHP.

Password_hash adalah salah satu fungsi yang dimiliki PHP untuk melakukan hashing menggunakan algoritma satu arah (one-way hashing). Fungsi ini terdapat pada PHP versi 5.5 ke atas.

Sedangkan Hash sendiri adalah suatu mekanisme untuk memetakan suatu data yang di-inputkan berupa teks polos (plain text) menjadi output berupa checksum atau fingerprint (kode acak dengan panjang karakter yang tetap).

Karena password_hash menggunakan algoritma hashing satu arah, maka data yang sudah ter-hash tidak akan bisa dikembalikan lagi menjadi data aslinya.

Misalkan saja kita memiliki sebuah password, kemudian password tersebut di-hash menggunakan fungsi password_hash(), maka password tersebut akan berubah menjadi kode acak seperti ini:

$2y$10$EnIi90KP.0BqCVJgK21BrO3xzArxCZaiAPaUebCw.K2Xw71QOCZv2

Contoh fungsi password_hash:

<?php
$options = [
    'cost' => 10,
];

echo password_hash("secret password", PASSWORD_DEFAULT, $options);

Kode di atas akan menghasilkan output:

$2y$10$EnIi90KP.0BqCVJgK21BrO3xzArxCZaiAPaUebCw.K2Xw71QOCZv2

Penjelasan kode di atas adalah sebagai berikut:

  • password_hash adalah fungsi yang digunakan untuk melakukan hashing.

  • secret password adalah password yang kita buat.

  • PASSWORD_DEFAULT adalah algoritma bawaan untuk melakukan hash yaitu menggunakan BCRYPT dan akan menghasilkan output sepanjang 60 karakter. Sangat disarankan untuk membuat field data pada database sepanjang 255 karakter, sebab output hasil hash dapat lebih panjang sesuai dengan algoritma yang digunakan.

  • $options hanya sebuah nama variabel array untuk menampung nilai cost. Nama variabel $options ini dapat kita ganti sesuka hati. Variabel $options ini tidak wajib.

  • cost adalah parameter yang digunakan untuk menentukan seberapa banyak hash dilakukan. Untuk BCRYPT, jika nilainya 10 maka proses hashing dilakukan sebanyak 2^10 atau 1024 kali.

Kode output hasil dari proses hashing tersebut kita simpan dalam database untuk membuat autentikasi login user dengan password_verify().

Password_verify adalah fungsi PHP yang berguna untuk melakukan verifikasi (mencocokkan) data yang telah ter-hash memakai fungsi password_hash().

Contohnya fungsi password_verify seperti ini:

<?php
$hashed = '$2y$10$EnIi90KP.0BqCVJgK21BrO3xzArxCZaiAPaUebCw.K2Xw71QOCZv2';

if (password_verify('secret password', $hashed)) {
    echo 'Password is valid!';
} else {
    echo 'Invalid password.';
}
  • $hashed adalah variabel untuk menampung nilai data yang dihasilkan dari proses hashing dengan fungsi password_hash().

  • password_verify adalah fungsi untuk mencocokkan data asli dengan data yang sudah ter-hash.

  • secret password adalah password yang kita buat.

Lebih jelasnya begini,

Fungsi password_verify akan mencocokkan data asli (secret password) dengan data yang ter-hash ($hash). Jika data cocok maka akan menampilkan pesan password is valid! dan jika tidak cocok maka akan menampilkan Invalid password.

Implementasi fungsi password_hash() dan password_verify()

Untuk menerapkan fungsi password_hash() dan password_verify() pada login aplikasi, silakan perhatikan dan amati contoh kode autentikasi yang sudah saya buat. Pada kode tersebut sudah saya tuliskan penjelasannya.

<?php
// Memulai session.
session_start();

// Jika ditemukan session, maka user akan otomatis dialihkan ke halaman admin.
if (isset($_SESSION['username'])) {
    header("location: admin.php");
}

// Include koneksi database.
require_once "connect.php";

// Jika tombol login ditekan, maka akan mengirimkan variabel yang berisi username dan password.
if (isset($_POST['login'])) {

    $username = $_POST['username'];
    $userpass = $_POST['password']; // password yang di inputkan oleh user lewat form login.

    // Query ke database.
    $sql = mysqli_query($connect_db, "SELECT username, password, nama FROM login WHERE username = '$username'");

    list($username, $password, $nama) = mysqli_fetch_array($sql);

    // Jika data ditemukan dalam database, maka akan melakukan validasi dengan password_verify.
    if (mysqli_num_rows($sql) > 0) {

        /*
            Validasi login dengan password_verify
            $userpass -----> diambil dari password yang di-inputkan user lewat form login
            $password -----> diambil dari password dalam database
        */
        if (password_verify($userpass, $password)) {

            // Buat session baru.
            session_start();
            $_SESSION['username'] = $username;
            $_SESSION['nama']     = $nama;

            // Jika login berhasil, user akan diarahkan ke halaman admin.
            header("location: admin.php");
            die();
        } else {
            echo '<script language="javascript">
                    window.alert("LOGIN GAGAL! Silakan coba lagi");
                    window.location.href="./";
                  </script>';
        }
    } else {
       echo '<script language="javascript">
                window.alert("LOGIN GAGAL! Silakan coba lagi");
                window.location.href="./";
             </script>';
    }
}
?>

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>Login dengan password_hash dan password_verify</title>
        <style type="text/css">
            body {
                font-family: Arial, serif;
                margin: 0;
            }
            .container {
                display: table;
                margin: 0 auto;
                height: 100vh;
            }
            .box {
                background: #eee;
                border-radius: 3px;
                padding: 20px;
                top: 30vh;
                position: relative;
                vertical-align: middle;
                margin: 0 auto;
                width: 275px;
                height: 175px;
            }
            .form-group {
                margin-bottom: 10px;
            }
            button {
                cursor: pointer;
                font-size: 16px;
                padding: 5px;
            }
        </style>
    </head>
    <body>
        <div class="container">
            <div class="box">
                <h2>Login</h2>
                <form action="" method="post">
                    <div class="form-group">
                        <label>Username :</label>
                        <input type="text" name="username" required>
                    </div>
                    <div class="form-group">
                        <label>Password :</label>
                        <input type="password" name="password" required>
                    </div>
                    <button type="submit" name="login">Login</button>
                </form>
            </div>
        </div>
    </body>
</html>

Agar lebih mudah mempelajari cara penerapan fungsi password_hash() dan password_verify(), silakan download source code login PHP di bawah ini:

Download source code

Fungsi password_hash sangat direkomendasikan untuk mengenkripsi password karena menggunakan algoritma hashing satu arah. Karena meskipun kita tau output password yang ter-hash, mustahil bagi kita untuk tahu password aslinya.

Jadi mulai sekarang, jika kalian akan membuat sebuah aplikasi dengan PHP, pastikan untuk menggunakan password_hash() dan password_verify() untuk keamanan loginnya.