I have been searching the web for a good tutorial on creating a script that allows someone to use a "enter password" field, and it then proceeds to allow them to access certain PHP pages.
I can only find tutorials that use both a USERNAME and PASSWORD (such as this tutorial- however i'm just looking for something that is secure, but uses one field only to authenticate.
Being a beginner, the only idea I have is to make the "username" field hidden, with the value of the actual username. I'm not sure how safe this is to do however, as i've heard it's dangerous to have hidden fields as they can be exploited?
I'm aware of SQL injection so i'm hoping to find something that is at least strong enough for that.
HTML:
<form action='login.php' method="post">
Password: <input type="password" name="password">
</form>
Login.php
<?php
// this password may come from any source.
// it's a variable for the sake of simplicity
$password = 'verySecretStuff';
if($_POST['password'] == $password){
//handle login
}else{
// handle no login
}
?>
If you just want to use a password, instead of a username+password combination, you just leave out the username part in the tutorials, so logging in would go like this:\
<?php
$password = 'unsafepassword1'; // received from a form post or whatever
$password = md5($password);
// Looking if this password is a valid password in the DB
$query = 'SELECT * FROM valid_passwords WHERE password = \''.$password.'\'';
IF(mysql_num_rows(mysql_query($query) == 1){
// user logged in
}
ELSE
{
// password was invalid
}
Just have a single input in your HTML (you don't need username at all):
<input type="password" name="password" />
And query the database as normal, just for the password:
$password = $_POST["password"];
$result = mysql_query("SELECT password FROM passwords WHERE password='" . some_hash_function($password) . "'");
if(mysql_num_rows($result) > 0) {
//There was a match
}
Update (based on comments on question)
If you want to allow access to multiple users with just a single widely known password, just store the password in your PHP script:
$password = "thePassword";
if(strcmp($password, $_POST["password"])) {
//Matched
}
Note that this is NOT particularly secure... the password is stored as plain text in the script. However, as you seem to want to multiple people to know the password, it's probably the simplest option. I would still suggest using a database to store the single password.
Well, the bad thing about it is that with username and password, you have to know the combination, user-password, with only password, it is easier to find out and a lot of users will just set some dumb passwords like: 654321 or birth date and stuff like that.
About the hidden fields, avoid them but if you really need it, use sessions instead.
Related
Well i have a problem. I have a registration for for legal users and natural users, but i need to write a validation in each php file for username checking, i have no idea how to combine two table checking.
one table is called users_legal, 2nd one is users_natural. In both forms name for input field is "username".
So far i have a code that checks passwords :
if ($password == $password_re)
{
// insert into table
$sql = $db->prepare("INSERT INTO users_legal(name, reg_number, address, phone, email, username, password) VALUES(?, ?, ?, ?, ?, ?, ?);");
$sql->bind_param("sssssss", $name, $reg_number, $address, $phone, $email, $username, $password);
$sql->execute();
$sql->close();
}
After makeing a validation in register forms, i also need it in login page. I figured out how to check if there is only and only one user with that username and that password, but i have no idea how to search them between tables.
login.php code :
if($_SERVER["REQUEST_METHOD"] == "POST") {
// username and password sent from form
$myusername = mysqli_real_escape_string($db,$_POST['username']);
$mypassword = mysqli_real_escape_string($db,$_POST['password']);
$sql = "SELECT id FROM login WHERE username = '$myusername' and password = '$mypassword'";
$result = mysqli_query($db,$sql);
$row = mysqli_fetch_array($result,MYSQLI_ASSOC);
$active = $row['active'];
$_SESSION['username'] = $myusername;
$count = mysqli_num_rows($result);
if($count == 1) {
session_register("myusername");
$_SESSION['username'] = $myusername;
$_SESSION['loggedin'] = true;
header("location: www.goole.lv");
}else {
$error = "Your Login Name or Password is invalid";
}
}
One more thing : i set my mysql to utf format, var_dump says that input is allright, but in mysql it saves in unbelievuble forms, like Ķegums or Skrīvelis.
Thnx for any examples, tips or whateva u got.
When I got you right, you have two tables with users. To validate if an user has logged in successfully you look up their login credentials in the related database table.
You are asking for 'combining' these two tables. But I don't think that that's what you want. You have two separate user tables. They do not belong to each other. If you join those tables, you might have dulicate unique user ids when combining these tables.
What you could do instead is check both tables separately, first for users_legal and second for users_natural.
You should also think about using password hashes instead of plain passwords in your db. And use pdo ;)
Good luck
To solve the problem of having two different types of users I would just put them in the same table and add a value that represents the user type for example 0 = legal and 1 = natural. This will also automatically prevent two users from sharing the same username. (This will only work for sure if the database is still empty, if not you might end up with two users with the same name). For the character encoding try setting mysql to utf-8 if you haven’t done it already (instead of just utf). Also you should never save passwords in plaintext. Use the sha1 function in php to convert them to their hash value before storing them. That way even if someone gets unauthorized access to the database they still won’t know the passwords. You should also append some user specific information to the password before hashing so that even if two users share the same password their hash values will be different. To verify if it’s correct you just apply the same procedure to the input before comparing it with the hash value you have stored.
I am trying to create a login system and hence I encrypted password during registration with the password_hash($password,PASSWORD_BCRYPT) function. However I am having difficulties while comparing the login password provided by the user with the bcrypted password stored in the database.
Here is the code without the security functions I tried while trying to compare the login password with the registered password. Any help would be greatly appreciated.
$loginpassword=$_POST['password'];
$con=mysqli_connect($ip,$username,$dbpass,$dbname);
$regpassword="SELECT password FROM customerdb WHERE username='$username'";
$result=mysqli_query($con,$regpassword);
$value=mysqli_fetch_fields($result);
if(password_verify($loginpassword,$value))
{
session_start();
header(.........);
exit();
}
P.S. I am using php 5.4. Hence I included the password_compat from https://github.com/ircmaxell/password_compat
The mysqli_fetch_fields method returns an array of metadata about the columns in the database, and not the values.
To get the password value, use mysqli_fetch_array. You also need to check a row was returned from the database.
$row = mysqli_fetch_array($result, MYSQLI_NUM);
if ($row) {
$value = $row[0];
// Verify...
} else {
// Invalid username
}
You should read up on SQL injection because your query is vulnerable to attack.
I am currently working on a website, it has a sign up PHP file that sends data to a database. For security measures, I set up a password encryption file that encrypts the password that the user enters, so that it is impossible to find in the database. Unfortunately, when the user tries to connect to the database from the log in PHP file, it denies them access to log in because the code connects to the database passwords, but it doesn't "sanitize" the password from it's encryption code, and the password isn't recognized by the server. I will provide my codes below:
Signup.php
$p = $_POST['p'];
$cryptpass = crypt($p);
include_once ("php_includes/randStrGen.php");
$p_hash = randStrGen(20)."$cryptpass".randStrGen(20);
Login.PHP
$p = md5($_POST['p']);
How do I change the Login.PHP line provided above so that it sanitizes the password from it's encryption value to the password the user actually knows and entered in the first place?
p.s. $p= The Password that the user enters
I'm going to add a second answer here, which is more of a safe guard when it comes to any user input you get that will be inserted or drawn from a database. When you MySql you want to sanitize any user input to prevent database injection which is the easiest way to break into a database.
Here is a great sanitation script. Start by making a separate PHP file and copy/paste this code into it.
<?php
// Sanitize User Input
function sanitize($data){
// apply stripslashes if magic_quotes_gpc is enabled
if(get_magic_quotes_gpc()){
$data = stripslashes($data);
}
// a mySQL connection is required before using this function
$data = mysql_real_escape_string($data);
return $data;
}
?>
Now include this page on any page that you will be interacting with the db
<?php require("sanitize.php"); ?>
Note: Before calling the function you must already be connected to your db
IE: mysql_connect("mysql",$mysqlusername,$mysqlpassword);
From here on out it is very simple. Say you assign a variable from a post like so
$password = $_POST["password"];
To sanitize this input you would do this
$password = sanitize($password);
This helps prevent MySql injections by removing certain characters relevant to modifying or revealing database information.
Hope this helps!
Ok, so once you get the password from the user you will want to encrypt it when inserting into your database. This requires an extra piece of data that is called "salt".
Salt is unique and you decide what you want it to be. But you will need it to encrypt and decrypt so it's important you do not lose it! I keep it in its own file and use an include whenever I need it. The following is PHP
$key_salt = 'lettersandnumbers';
Now for the password encrypting
Say you have the username and password in variables like so...
$user_id = "usersId";
$password = "usersPassword";
This is the way to put them into the database...
Create a variable with the following data
$insertdata = sprintf("INSERT INTO $table (user_id, password,) VALUES ('%s', AES_ENCRYPT('%s', '$key_salt'))", $user_id, $password);
mysql_query($insertdata);
Notice the AES_ENCRYPT('%s', '$key_salt') This is what is making the encryption and see how it uses the $key_salt along with the '%s' (which is the $password)
The combination of these makes it nearly impossible to crack
This will decrypt the password and put it into a variable then you can do what you want with it after that....
$results = mysql_query("
SELECT AES_DECRYPT(password, '$key_salt') as password FROM $table where AES_DECRYPT(password, '$key_salt')='$password'");
$row = mysql_fetch_array($results);
$decryptedpassword = $row['password'];
Do not concatenate crypted password with random characters unless you save them also in database, otherwise - you will never be able to compare user input with saved encrypted password. Just use:
$p_hash = $cryptpass;
and in Login.php script do not use md5($_POST['p']); which is different hashing method, but use also crypt() function:
$p = crypt($_POST['p']);
I am trying to set up a secure login & register system using crypt() as I have read that that is php's stored function for bcrypt
I am registering a user but taking their password and and then crypting it.
$hashed_password = crypt($mypassword);
I then store $hashed_password in the db
then when the user logs in I am trying to match the password to whats stored.
I found this function on php.net but cant get it to work
$password is the stored crypted password and $mypassword is the users input
if ($password == crypt($mypassword, $password)) {
echo "Success! Valid password";
}
I understand that crypt generates a unique hash each time its called so I dont understand how the function can work.
Am I completeley missing the point as I read that crypt() is a one function and decrypt does not exist?
any help greatly appreciated in not only showing the error of my ways but also in completing this secure login
You're using second parameter in your crypt() call, so it's treated as salt. To compare properly, you can use:
if ($password == crypt($mypassword))
{
echo "Success! Valid password";
}
But PHP provides native functionality for hashing routines - it is introduced if 5.5 version and called password hashing.
For PHP versions below 5.5 down to 5.3.7, there is a backported compatibility function that does the same: https://github.com/ircmaxell/password_compat Just include it and use it.
But note that you have to read the hashed password from the database and then compare it with PHP. You cannot query the database with a newly created password hash to find the user.
Assuming that the encrypted password from the database is $db_pass and the entered password is $new_pass. Then here's how you test it:
if($db_pass === crypt($new_pass)){
echo "Success!";
}
This post will help...
Assuming the current database is reading the password, all we have to do is:
} elseif (crypt($pass, $row['pass']) == $row['pass']) {
There are few steps you need here..this tutorial will help however:
http://www.wikihow.com/Create-a-Secure-Login-Script-in-PHP-and-MySQL
Essentially you want to have the password encrypted in the database - eg. so if the password as 'mypassword' it would be stored in some random string like '3ifdgk5ty=-dlsfs'.
Read up on sha1 (md5 is no longer considered secure). Never used crypt myself however sha1() seems to do the job for me when used in conjunction with a salt (an additional text string added to the password to make it harder to break hack)
You can not decrypt it, because hash is one way. So you can not obtain the original input via hash. You can not reveal users passwords even if you have access to the database.
It is being used like this:
user writes password into input -> submits form -> password goes into database like following:
sha1($_POST['password']);
then you store this hashed password in database.
Whenever user wants to log in, he submits form again and it does this logic ($result['password']) comes from the database query:
if(sha1($_POST['password']) == $result['password']) {
//password match, so lets log you -> set sessions, cookies and so on
}
I am doing a security audit on my login logic and trying to figure out which password check is more secure, and the better algorithm. Below are the two methods in pseudo PHP code:
Method I:
$bcrypt = new Bcrypt();
$password_hash = $bcrypt->hash($_POST['password']);
$result = mysqli_query_check_login($username, $password_hash);
if(mysqli_numb_rows($result) > 0) {
//is valid
}
Method II:
$bcrypt = new Bcrypt();
$result = mysqli_query_check_login($username);
//Note $result->password is a bcrypt hash
if($bcrypt->verify($_POST['password'], $result->password)) {
//is valid
}
The difference is method I runs bcrypt hash and then sends the username and hashed password in the mysql query. Method II gets the hashed password from mysql via the username only and then in PHP compares the two values.
Is there any security difference?
Thanks.
These are effectively the same thing. There should be no security implications in using either method.
Method II would probably make it simpler to get the user's information and update something like a "failed login attempts" counter. Most implementations I've seen for Method I simply rely on WHERE user=$login AND password=$password not selecting the user if the password doesn't match.