Jump to content

Recommended Posts

Hi,

 

Maybe someone here can give me an opinion.  So i'm trying to implement your standard "key and lock" system for a login for my website.  Instead of using a username and password, I wanted to use a grid of pictures, which when clicked in the correct sequence, would permit access.  Nothing too revolutionary here or particularly high security, but I thought it would be fun.

 

So, I have 25 different images on my server, and when I click through the links, nothing happens.  Basically, my code doesn't work, and now i'm depressed.  Any thoughts as to why?

 
<html>
<body>
 

<?php
 
class fortress {
 
function lockandkey ($checkforkeys){
 
$gate1= "[url=http://www.mywebsite.com/01.png]http://www.mywebsite.com/01.png[/url]";
$gate2= "[url=http://www.mywebsite.com/02.png]http://www.mywebsite.com/02.png[/url]";
$gate3= "[url=http://www.mywebsite.com/03.png]http://www.mywebsite.com/03.png[/url]";
$gate4= "[url=http://www.mywebsite.com/04.png]http://www.mywebsite.com/04.png[/url]";
$gate5= "[url=http://www.mywebsite.com/05.png]http://www.mywebsite.com/05.png[/url]";
$gate6= "[url=http://www.mywebsite.com/06.png]http://www.mywebsite.com/06.png[/url]";
$gate7= "[url=http://www.mywebsite.com/07.png]http://www.mywebsite.com/07.png[/url]";
 
if ($gate1 == $gate1) {($key1=1);}
else if  ($gate1 != $gate1) {($key1=0);}
 
if  ($gate2 == $gate2) {($key2=1);}
else if  ($gate2 != $gate2) {($key2=0);}
 
if  ($gate3 == $gate3) {($key3=1);}
else if  ($gate3 != $gate3) {($key3=0);} 
 
if  ($gate4 == $gate4) {($key4=1);}
else if  ($gate4 != $gate4) {($key4=0);}
 
if  ($gate5 == $gate5) {($key5=1);}
else if  ($gate5 != $gate5) {($key5=0);}
 
if  ($gate6 == $gate6) {($key6=1);}
else if  ($gate6 != $gate6) {($key6=0);}
 
if  ($gate7 == $gate7) {($key7=1);}
else if  ($gate7 != $gate7) {($key7=0);} 
 
$accessgranted=7;
 
if 
 
($key1 + $key2 + $key3 + $key4 + $key5 + $key6 + $key7 == $accessgranted)
 
{($fortressopen);}
 
else if 
 
($key1 + $key2 + $key3 + $key4 + $key5 + $key6 + $key7 != $accessgranted)
 
{($fortressclosed);}
 
$fortressopen =     "<a href= [url=http://www.zebradatasolutions.com/main.php]http://www.mywebsite.com/main.php[/url] </a>";
$fortressclosed =   "<a href= [url=http://www.zebradatasolutions.com/loginfailed.php]http://www.mywebsite.com/loginfailed.php[/url] </a>";
 
}
 
}
 
?>
 
<body bgcolor="#000000" text="#FFFFFF" link="#FF0000">
<p style="text-align: center; font-family: 'Courier New', Courier, monospace; font-size: 24px; color: #FFF;">GATE ONE</p>
<div align="center">
  
  <table width="48%" height="358" border="0" cellpadding="10" cellspacing="10">
    <tr bgcolor="#333333" style="text-align: center">
    
      <td><a href="gate2.php <?php echo new fortress;?>"><img src="01.png" width="100" height="100" /></a></td>
      <td><a href="gate2.php <?php echo new fortress;?>"><img src="02.png" width="100" height="100" /></a></td>
      <td><a href="gate2.php <?php echo new fortress;?>"><img src="03.png" width="100" height="100" /></a></td>
      <td><a href="gate2.php <?php echo new fortress;?>"><img src="04.png" width="100" height="100" /></a></td>
      <td><a href="gate2.php <?php echo new fortress;?>"><img src="05.png" width="100" height="100" /></a></td>
    </tr>
    <tr bgcolor="#333333" style="text-align: center">
      <td><a href="gate2.php <?php echo new fortress;?>"><img src="06.png" width="100" height="100" /></a></td>
      <td><a href="gate2.php <?php echo new fortress;?>"><img src="07.png" width="100" height="100" /></a></td>
      <td><a href="gate2.php <?php echo new fortress;?>"><img src="08.png" width="100" height="100" /></a></td>
      <td><a href="gate2.php <?php echo new fortress;?>"><img src="09.png" width="100" height="100" /></a></td>
      <td><a href="gate2.php <?php echo new fortress;?>"><img src="10.png" width="100" height="100" /></a></td>
    </tr>
    <tr bgcolor="#333333" style="text-align: center">
      <td><a href="gate2.php <?php echo new fortress;?>"><img src="11.png" width="100" height="100" /></a></td> 
      <td><a href="gate2.php <?php echo new fortress;?>"><img src="12.png" width="100" height="100" /></a></td>
      <td><a href="gate2.php <?php echo new fortress;?>"><img src="13.png" width="100" height="100" /></a></td>
      <td><a href="gate2.php <?php echo new fortress;?>"><img src="14.png" width="100" height="100" /></a></td>
      <td><a href="gate2.php <?php echo new fortress;?>"><img src="15.png" width="100" height="100" /></a></td>
    </tr>
    <tr bgcolor="#333333" style="text-align: center">
      <td><a href="gate2.php <?php echo new fortress;?>"><img src="16.png" width="100" height="100" /></a></td> 
      <td><a href="gate2.php <?php echo new fortress;?>"><img src="17.png"  width="100" height="100" /></a></td>
      <td><a href="gate2.php <?php echo new fortress;?>"><img src="18.png" width="100" height="100" /></a></td>
      <td><a href="gate2.php <?php echo new fortress;?>"><img src="19.png" width="100" height="100" /></a></td>
      <td><a href="gate2.php <?php echo new fortress;?>"><img src="20.png" width="100" height="100" /></a></td>
    </tr>
    <tr bgcolor="#333333" style="text-align: center">
      <td><a href="gate2.php <?php echo new fortress;?>"><img src="21.png" width="100" height="100" /></a></td> 
      <td><a href="gate2.php <?php echo new fortress;?>"><img src="22.png" width="100" height="100" /></a></td>
      <td><a href="gate2.php <?php echo new fortress;?>"><img src="23.png" width="100" height="100" /></a></td>
      <td><a href="gate2.php <?php echo new fortress;?>"><img src="24.png" width="100" height="100" /></a></td>
      <td><a href="gate2.php <?php echo new fortress;?>"><img src="25.png" width="100" height="100" /></a></td>
    </tr>
  </table>
</div>
</body>
</html>
 

It's important to note that each page has the same code, but the only thing that changes is the link to the next "gate."

 

Cheers

Edited by ignace
Added code tags
Link to comment
https://forums.phpfreaks.com/topic/277566-having-trouble-with-this-idea/
Share on other sites

if ($gate1 == $gate1)

What else would it ever equal?

 

Edit for more observations:

{($fortressopen);}

else if 


($key1 + $key2 + $key3 + $key4 + $key5 + $key6 + $key7 != $accessgranted)


{($fortressclosed);}


$fortressopen =     "<a href= http://www.mywebsite.com/main.php </a>";
$fortressclosed =   "<a href= http://www.mywebsite...loginfailed.php </a>";

You defined $fortressopen and $fortressclosed after using them. That's surely not going to help things along.

Edited by captbeagle

Also, my idea was that the "correct" key has a value of 1, and the "incorrect" keys have a value of 0.  So, if the sequence is correct, that will equal 7.  Nonetheless, I am having trouble passing these values from page to page.  

 

Maybe it's something very basic here, or this could be much more complicated.  Anyone have any ideas?

Hmm.  These are good observations.  I didn't realize it matters where you put a variable inside a class.  Can you tell me why?

 

You don't have to initialize variables in PHP, but if you don't, they'll have some default value depending on the context in which they're used (eg, integers and floats default to 0).  In your case, you're trying to output a link - it's simply going to output an empty string since you haven't otherwise initialized it yet.

 

Take a look at http://www.php.net/manual/en/language.variables.basics.php

My take is that you should be looking at arrays:

 

<?php
session_start();
//editable variables:
$correctLockSequence = array(1,2,3,4,5,6);
$lockURI = 'http://www.mywebsite.com/main.php';
$lockOpenedURI = 'http://www.mywebsite.com/passed.php';
$lockBarricadedURI = 'http://www.mywebsite.com/loginfailed.php';
 
//dynamic variable knowledge base:
$numberOfLocks = count($correctLockSequence);
 
//starting processing:
//get the lock number sent in the URL:
$currentLockNumber = (isset($_GET['lock'])) ? $_GET['lock'] : 0;
//Lets us know that the lock rotation is NOT complete.
$rotationComplete = false;
 
//set our current selected lock in the session array:
$_SESSION['selectedLocks'][] = $currentLockNumber;
 
//if our number of locks selected is equal to the number of locks needed:
if(count($_SESSION['selectedLocks']) == $numberOfLocks) {
//then our rotation is complete.
$rotationComplete = true;
//but our page is locked:
$pageLocked = array();
//so we look at each index in the array:
 foreach($_SESSION['selectedLocks'] as $key => $lock) {
//if each index does equal the corresponding index in the correctly sequenced array: (unlock the page, else lock it down)!
   if($correctLockSequence[$key] == $lock) {
     $pageLocked[] =0;
   } else {
     $pageLocked[] = 1;
   }
 }
 
//redirects:
//if the rotation is not complete, go get another lock code:
if($rotationComplete == false) {
  header('Location: ' . $lockURI);
  exit();
} elseif(in_array(1,$pageLocked)) { //else if rotation is complete, and some keys did not match, then barricade the store:
  header('Location: ' . $lockBarricadedURI);
  exit();
} else { //else everything matched up, and you can let them in.
  header('Location: ' . $lockOpenedURI);
  exit();
}

 

 

 

 

 

 

Dear Bones,

 

Could you elaborate as to why you believe this would work better?  I was hoping my implementation was at least workable in some form.  Do you believe it is not workable at all?  If so, what problems do you see?

 

Kind Regards...

Also, you definitely made me aware of something here.  This idea cannot work without a session in play because those variable values cannot be passed to each successive page without a session.  This is most likely why it is not working.  

 

Again, bones, can you elaborate a bit more if I can do something with the code I wrote?  I just have a hard time using someone else's code if you don't mind sir.

 

Again,

 

Kind Regards

I just think the logic flows better with arrays.  Right now you are trying to compare if all of the values end up the same a the access key:

 

($key1 + $key2 + $key3 + $key4 + $key5 + $key6 + $key7 != $accessgranted)

 

This will work NO MATTER HOW the keys are chosen.  The sequence could be reversed and they would still get the access.  Matter of fact, there could be 1,000's of different sequences that  you could come up with that would equal the pass code in that one line of code.

 

With arrays, you can be sure that the pass code was clicked in the correct order.

I appreciate the insight here.  I am trying to pear this code down to be as short as it can possibly be.  I have implemented session variables and it still does not work. 

 

With PHP, it seems there is no way to log every step so that I can know what is going wrong.  If you can't identify where things are going wrong, how can you ever fix the problem?

 

Does anyone know a way I can see the logic flow?

session_start();

// our sequence container
if (!isset($_SESSION['sequence']) || (isset($_GET['sequence']) && $_GET['sequence'] === 'clear')) {
  $_SESSION['sequence'] = array();
}

// user passed a code, store the code in the sequence container
if (isset($_GET['code'])) {
  $_SESSION['sequence'][] = (int) $_GET['code'];
}

// user asked us to verify what is currently in the sequence container (omit if empty)
if (isset($_GET['verify']) && !empty($_SESSION['sequence'])) {
  $db = mysqli_connect('host', 'user', 'pass', 'db') or die('Database has left the building!');
  if ($stmt = mysqli_prepare('SELECT username FROM users WHERE password_sequence = ?')) {
    $sequence = implode(',', $_SESSION['sequence']);
    $stmt->bind_param('s', sha1($sequence));
    $stmt->execute();
	
    $stmt->bind_result($username);
    $stmt->fetch();
	
    echo 'Hello, ', $username;
    exit;
  }
}

// our numbers
$numbers = range(1, 10);

// corresponding images
$images = array_combine(
  $numbers,
  array_map(function($i) { return sprintf('%02d.jpg', $i); }, $numbers)
);

// display images
foreach ($images as $number => $image) {
  printf(
    '<a href="?code=%d"><img src="%s" alt="" width="100" height="100"></a>',
	$number, $image
  );
}

// display verify link
echo '<a href="?verify=1">verify</a>';
A user can create a sequence as long as he likes (just like a password, the longer the better). When he presses verify the currently stored codes are converted to a string and separated by a , so that a sequence of 1,2 and 12 do not match the same thing. The sequence is then encrypted with sha1 (the same rules as with a password still apply here). For this to work you need a UNIQUE constraint on the password_sequence. No 2 people can have the same sequence.

 

This of course imposes a problem because a hacker would now be able to simply enter simple sequences to login to someone's account (without having to know their username or e-mail or any other info). So to put the security at the same level as a normal login you need to provide a username field.

Edited by ignace

Hello Again Guys,

 

First off I want to say thanks to everyone who has been kind enough to chime in.  I wanted to post a link to my website to show how I am implementing this.  The idea of a "sequence container" is something new and foreign to me.

 

ignace... could you describe this piece of code a bit more in detail? 

 

// our numbers
$numbers = range(1, 10);

// corresponding images
$images = array_combine(
$numbers,
array_map(function($i) { return sprintf('%02d.jpg', $i); }, $numbers)
);

// display images
foreach ($images as $number => $image) {
printf(
'<a href="?code=%d"><img src="%s" alt="" width="100" height="100"></a>',
    $number, $image
);
}

// display verify link
echo '<a href="?verify=1">verify</a>';

 

 

www.zebradatasolutions.com/gate1.php

 

Right now it's just a loop because it doesn't work, but with time maybe...

You don't need multiple gate*.php files. One file will do. Every time you click on an image it sends you to the same page with a different ?code=X, it stores these codes and when the user clicks verify it tries to find a match in the database containing the entered codes.

 

Suppose my sequence is the images clicked in this order: 1, 7, 13, 19, 25 (diagonal) then I would send the following requests:

 

gate1.php?code=1

gate1.php?code=7

gate1.php?code=13

gate1.php?code=19

gate1.php?code=25

 

I have entered my sequence and therefor I send the last request:

 

gate1.php?verify=1

 

The database is queried a match is (hopefully) found and I am logged in.

Edited by ignace

So if I am understanding this correctly, we are using the array_map function to keep a record of the array in a session.  The arrays correspond to an image in a MYSQL database, and from there, if the users pattern of images lines up with the array sequence in the database, for example:

 

array (image 1, image 7, image 9, image 17, image 20, image 21, image 25)

 

Then we have access.

 

This makes sense.  I don't have the skill to implement it (not yet anyway), but it makes sense.

DEAR IGNACE,

 

I agree that it would be okay to have one page... let's get into this a bit more since I have your attention.  It is divided into "gates" for a specific reason (in my mind anyway.)  My hope is to develop a cryptographic login system based on images.  The odds of breaking such a system, if coded correctly, are 1 in 95 trillion or more.  

 

For example, if there are 10 "gates" and 25 symbols, choosing all ten correctly in order would equal 25 to the power of 10:

 

1 in 95,367,431,640,625

 

...thats 95 trillion 367 billion... 

 

And I believe that hashing algorithms and AES 256 are possibly becoming outdated.

 

This is just an idea, but it's more like a puzzle.  I am assuming that someone will jump in here and tell me why this won't work, but I have coded some fairly complex algorithms in C and C++.  The problem is I am not too experienced with PHP.

 

Soooo... hoping that I don't get laughed off this forum, this is mostly an idea.  I was hoping to not involve MYSQL and maybe even not use sessions but that may be unavoidable. 

 

Also, maybe someone can answer the $$$ million dollar question here.  If the images are dynamic, let's just say they move with every reload, and they are coming from a database, does that decrease my security?

 

How long would a brute force attack take to crack something like this?  How would a brute force attack even recognize images?

 

This is why I wanted to stay away from using a database.  I was hoping that the "keys" could be stored in the code itself, which may seem strange, but I may want to use this on a microcchip in the future.

No. He is my code again more thoroughly documented.

 

/**
 * We start the session here to store our steps between requests.
 */
session_start();

/**
 * If the 'sequence' does not yet exist, create it. Or clear it if ?sequence=1 is passed.
 */
if (!isset($_SESSION['sequence']) || (isset($_GET['sequence']) && $_GET['sequence'] === 'clear')) {
  $_SESSION['sequence'] = array();
}

/**
 * When a user clicks an image it will contain ?code=X we check here if this is the case
 */
if (isset($_GET['code'])) {
  /**
   * It is. Store the code in our session so that it persists between requests.
   */
  $_SESSION['sequence'][] = (int) $_GET['code'];
}

/**
 * User appears to be finished and asks us to find the user with this sequence.
 * Just to be sure we check if 'sequence' infact contains codes.
 */
if (isset($_GET['verify']) && !empty($_SESSION['sequence'])) {
  $db = mysqli_connect('host', 'user', 'pass', 'db') or die('Database has left the building!');
  if ($stmt = mysqli_prepare('SELECT username FROM users WHERE password_sequence = ?')) {
    $sequence = implode(',', $_SESSION['sequence']);
    $stmt->bind_param('s', sha1($sequence));
    $stmt->execute();
	
    $stmt->bind_result($username);
    $stmt->fetch();
	
    echo 'Hello, ', $username;
    exit;
  }
}

/**
 * Creates an array with numbers from 1..10
 */
$numbers = range(1, 10);

/**
 * Create an array with key=>value pairs where key is the number and the value is the image.
 * 
 * In other words the result will look like:
 *  array ( 1 => '01.jpg', .. )
 */
$images = array_combine(
  $numbers,
  array_map(function($i) { return sprintf('%02d.jpg', $i); }, $numbers)
);

/**
 * Display the images to the user
 * 
 * This outputs:
 *   <a href="?code=1"><img src="01.jpg" alt="" width="100" height="100"></a>
 */
foreach ($images as $number => $image) {
  printf(
    '<a href="?code=%d"><img src="%s" alt="" width="100" height="100"></a>',
	$number, $image
  );
}

// display verify link
echo '<a href="?verify=1">verify</a>';

It is divided into "gates" for a specific reason (in my mind anyway.) My hope is to develop a cryptographic login system based on images. The odds of breaking such a system, if coded correctly, are 1 in 95 trillion or more.

1. The hacker knows each password has 10 symbols (no way to stop after 5 for example), so it is a limited finite set. So 95,367,431,640,625 is highly exaggerated.

2. User's can't go beyond 10 gates, so "passwords" can't be made stronger. Which is not a problem in my above code, a user can select one code or 1000.

3. Your system has the same weaknesses a normal password has suppose someone selects the first image of each gate.

4. Because you require no username all "passwords" have to be unique otherwise 2 people can no longer login. Because "passwords" have to be unique it's possible for someone to unwillingly hack someone else's account. Just like you have collisions with regular passwords.

 

And that is just out of the top of my hat.

 

If the images are dynamic, let's just say they move with every reload, and they are coming from a database, does that decrease my security?

No, what this does is make it harder for anyone to login (they have to remember the exact symbols in the exact order) while a hacker just simply uses a script to send the sequence.

 

How long would a brute force attack take to crack something like this? How would a brute force attack even recognize images?

It doesn't need to recognize images you send the user from gate1 to gate2 with an identifier. The script would simply query each gate with a new set.

Edited by ignace

Fair enough.  I was thinking this could be an "extra" measure of security... meaning that once someone is logged in, this puzzle would show up. 

 

I think it is a cool idea because...

 

USERNAMES and PASSWORDS get compromised all the time.

 

I am not sure as to the validity of your claim that my numbers are exaggerated.  

 

Powerball players know there are 7 numbers, and 50 to chose from, but very few ever win.  I believe the odds are as good as I am saying they are.  I could always be mistaken though.

 

I don't want you to think I am back tracking.  I am going to try to work with your suggestions for sure.  

Powerball players know there are 7 numbers, and 50 to chose from, but very few ever win.

I think the lottery is a bad reference, I don't know how poweball lottery works but if it's lottery like we have it, every week somebody wins and sometimes multiple people guess the same numbers. So there is a high collision rate. Not preferable for something that should beat AES256.

 

I believe the odds are as good as I am saying they are.

It doesn't matter how good or bad the odds are, there is still a thing called usability.

 

Show a person the 25 images and let them select 1 each time, tell them to remember it, note their choices down. After 10 symbols are selected ask them to repeat the symbols in the correct order. The odds of someone repeating the symbols in the correct order is as slim as an attacker trying to brute-force their way in.

 

Not to mention that there are already ways to bypass the "flaws" of md5 or sha1 or the like. Which is why most now use PBKDF2 (designed to be slow so that decrypting takes years not mere minutes/seconds like hashing algorithms) and people are encouraged to use phrases (easier to remember, longer then passwords, and harder to crack) instead of passwords. Which achieves the goal without getting in the way of users.

Edited by ignace
This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.