Not so much a question as a review request. I am currently working on an app which needs to authenticate a user against an existing Joomla database which I have access to. As the password field in the database holds an encrypted password (and I can find no ready-to-go solution), I set about creating my own…
Although my need is related to an iOS app which I am developing, I believe that it is a workable solution for general use
Looking at the hashed passwords, I realised that they were in Blowfish format so that - knowing the password - I should be able to extract the salt then use it to hash the user's password before attempting to authenticate.
The code assumes a working knowledge of Joomla / MySQL / PHP / JSON queries
<?php require("conf.php"); $conn = new mysqli($host, $username, $password, $database); // if there is some error connecting to the database // with die we will stop the further execution by displaying a message causing the error if ($conn->connect_error) { die("Connection failed: " . $conn->connect_error); } // Check that it is a POST request. if(strcasecmp($_SERVER['REQUEST_METHOD'], 'POST') != 0){ throw new Exception('Request method must be POST!'); } // Check that the content type of the POST request has been set to application/json $contentType = isset($_SERVER["CONTENT_TYPE"]) ? trim($_SERVER["CONTENT_TYPE"]) : ''; if(strcasecmp($contentType, 'application/json') != 0){ throw new Exception('Content type must be: application/json'); } // Receive the RAW post data. $content = trim(file_get_contents("php://input")); // ttempt to decode the incoming RAW post data from JSON. $decoded = json_decode($content, true); // If json_decode failed, the JSON is invalid. if(!is_array($decoded)){ throw new Exception('Received content contained invalid JSON!'); } // Get username and password from POST data $username = $decoded["username"]; $pass = $decoded["password"]; //creating an array for storing the data $userDetails = array(); // Get stored password field from db and store in variable $sql = "SELECT password FROM ".$dbprefix."users WHERE username = '$username'"; $stmt = $conn->prepare($sql); $stmt->execute(); $result = $stmt->get_result(); $row = $result->fetch_assoc(); $encryptedStr = $row['password']; // Process password from DB extracting salt and hash value $bits = array(); $salt = substr($encryptedStr, 7, 22); $hash = substr($encryptedStr, 29); $crypted = crypt($pass, "$2y$10$".$salt); // Add to JSON for information - not necessary for live site array_push($bits, "From DB: ".$encryptedStr); array_push($bits, "Crypted: ".$crypted); array_push($bits, "Salt: ".$salt); array_push($bits, "Hash: ".$hash); array_push($userDetails, $bits); // SQL statement using password in same format as DB - in the example, // using the id field - however any other field will do $sql = "SELECT id FROM ".$dbprefix."users WHERE username = '$username' AND password = '$crypted'"; $stmt = $conn->prepare($sql); $stmt->execute(); $result = $stmt->get_result(); $row = $result->fetch_assoc(); $id = $row['id']; // Add user id to JSON array_push($userDetails, $id); // Return JSON from server echo json_encode($userDetails);