Introduction

I came up with the concept for this after watching Die Hard 4.0 where the White Hat hacker in the movie had written what he called a "mutating security algorithm". I thought that it might be useful to have a system that changes (or mutates) passwords if a login fails enough times that it might present a security risk.

This login system is not like your conventional system. Classic login systems rely on a defined username and password combination to allow users access to private information. A lot of people don't often use sufficiently strong passwords when they register to be part of a community website or even when they set their login information on internet banking systems.

These passwords are normally things like birthdates or names that have meaning to the registrant. This is where the security risk comes in.
A plausible scenario would be a situation in which a woman signs up for facebook and sets her password as her daughter's full name. Friends of hers on facebook that may be feeling "mischievous" might guess that her password has something to do with her daughter, and make attempts at guessing her login details.

In this situation, a classic login system would allow for an unlimited number of guesses during which the "attacker" might eventually guess right and gain access.

This login system addresses such a situation and provides more security to the registered user.

Background

This system was written in Visual Basic.NET and uses a SQL Server database for storage of user information. Most user data is stored as plain text, with the exception of the user's password which is encrypted using SHA1.

Challenges during development were small issues around the encryption of the user's password as well as the tracking of login attempts through the use of a session variable which gets counted on each attempt. These issues were purely conceptual in nature and were resolved relatively quickly.

How It Works

Upon registration, a new user will be sent an email which will contain details about his/her account. These details include their user id, username, and password.
To log in, the user will have to enter their user id first to verify that they indeed do have an account on the system. Once the user id is verified, they will be asked to supply the username and password that is associated with the user id that they entered.

Where there are less than 3 login attempts on record for the current session, the login hashes and salts the value entered into the password field on the login form, and selects a record with user id, username, and password value that are identical to user input. If this selection doesn't return a single row from the database, the login was invalid and an attempt gets counted in the user's session.

Should there be 3 login attempts counted, the account is flagged as locked and, until such time as it is recovered by the user, will not be included in selection for future login attempts.In addition, a 36 character long value is generated after the account gets locked. This value is then hashed and salted and stored in the database as the new password for the account.

What this release contains

This release contains the basic security "measures". Due to challenges with free time, I haven't been able to add the code to process the emails yet.

Currently included are:

Functions to handle SHA1 encryption of user passwords

General session management that keeps track of login attempts

Bare-bones user interface used while testing. This has not been cleaned up in this version.

Plans for the future

I always like it when I can find software that works on multiple platforms, so I'll be working on a PHP version that uses mysql as a data backend.

To put any security worries to bed, the next version will include functionality to redirect users off of the login page if they are currently logged in to their account.

Probably the most crucial change in the works will be the modification of the user id from an integer field to a guid(). This will eliminate the possibility of user ids being guessed and make "spoofing" another user's account a lot more complicated.

Using the code

Before you can use this system, you'll need to change the connection strings. Currently each file that works with the data source has one in it:

Create.aspx.vb

Login.aspx.vb

' This is what the connection string currently looks like:
Private connstr AsString = "Data Source=.\SQLEXPRESS; Initial Catalog=test; Integrated Security=True;"' The values for Initial Catalog and Data Source will need to be changed in order for the system to work correctly with your database.

Only one table is needed for the system to function correctly. The table must include the following structure for the system to work correctly.

Share

About the Author

I started coding back in high school. My "Computer Science" subject for grade 10 was actually an introduction to programming in Delphi. I struggled a lot and was fairly disheartened and frustrated by the time I got to the end of the book.
That changed, though, when I found an introduction to HTML in the back after all the Delphi. I was hooked! It was simple and I could see the results of my work as I did it.

I kept teaching myself over the years and branched out into other languages as I found my requirements changing.
The first "server-side" tech I learnt was asp.net with visual basic code behind.

Now that I'm working with it as a day job, I've moved over to PHP for my personal projects, so the learning continues.

When I'm not coding, I'm either playing World of Warcraft, some other game or hanging out with friends. I enjoy playing pool and ice skating as "extra curricular" activities.

Comments and Discussions

The quality is still poor, and the application can easily be hacked using a network sniffing tool (WireShark, for example).
If you want to learn about security concerns I'd recommend you to have a look at this article by Espen Harlinn. He explains the basic concerns of security quite well.

It seems strange to me that in most cases (and I'm not talking about online banking/shopping where highly sensitive financial data is passed around), simple password encryption is sufficient for almost everyone, but here I am exploring the idea that maybe something more can be used to build on that simple encryption and all anyone's ever said on the matter is how sh*t it is...

You see, this was always just an idea. One that I have, until recently, forgotten about. What this article did was to show me that the programming community of the world doesn't like innovation. Nobody has come to me saying anything like "nice idea, it has potential, but here's some problems with it: xyz. Would you be open to collaboration with me to improve on it? Maybe we can deliver something that is properly world class".

No, it's always just been "this sucks and you don't have a shitting clue what you're doing". When I wrote this, I really wanted to develop my abilities in terms of security. I was learning about penetration testing, hashing, salting, all of it... but this community has been so negative and destructive about this article that I quickly lost all motivation to even bother going anywhere with any of it.

While I appreciate your recommendation, I'm afraid I really don't care enough anymore to even think about opening that article you linked.

It seems strange to me that in most cases (and I'm not talking about online banking/shopping where highly sensitive financial data is passed around), simple password encryption is sufficient for almost everyone

No it is not. They send you an additional pin as SMS to confirm your identity. Furthermore, the connection is SSL encrypted.

ortund wrote:

on the matter is how sh*t it is...

I did not say that it is sh*t, and I am ready to revote the article when you improved it.

ortund wrote:

What this article did was to show me that the programming community of the world doesn't like innovation.

Innovation is good, but after how you presented the so called Innovation I just do not get the point how your solution may be a plus for the security of login.

ortund wrote:

Nobody has come to me saying anything like "nice idea, it has potential, but here's some problems with it: xyz. Would you be open to collaboration with me to improve on it? Maybe we can deliver something that is properly world class".

I'd love to collaborate, but I simply do not have the time at the moment.
I am sorry if I was not clear enough about the actual issues:
-> What is the innovation? It is common practice, in critical medical applications for example, to lock the account after three failed login attempts and regenerate a new password
-> You do not explain how you actually do the hashing and salting

My suggestions to improve the article:
-> Go away from the focus of "What happens when the login fails three times" and go rather for something like "How to store a password securely" - explain the hashing & salting, and describe what you do when a user sets a new password, a user requests a new password or a user logs into the system.
-> Explain the code carefully. Every method you wrote by yourself should be explained step-by-step (What does it? Why? How?).

ortund wrote:

No, it's always just been "this sucks and you don't have a shitting clue what you're doing". When I wrote this, I really wanted to develop my abilities in terms of security. I was learning about penetration testing, hashing, salting, all of it... but this community has been so negative and destructive about this article that I quickly lost all motivation to even bother going anywhere with any of it.

I hope my suggestions are constructive for you to improve the article.
However, security is not only defined in just "What do I do when a user fails to login?". It is about "How can I prevent people from stealing data", too. You learned about hashing and salting, a topic which is not very good covered on CodeProject yet. That is good. Now it is at you to pick up the topic and make an explanation about hashing and salting, which would be appreciated by many community members.

And I hope I was able to correct the picture you have about our community!

Please, if you have further questions about how to write a good article, feel free to get back to me!

Instead of passing down judgement, how about you help people to understand?
This was just an idea I had. Of course it'll get better with more understanding, but as long as people like you whine about people like me not understanding, how can anything develop?

Do something helpful and write an intro to basic web security or something rather than slapping people in the face for doing things wrong when they're starting out.

Don't even know why I bothered with this site... Seems to me that it's just full of stuck up pricks who think they're god's gift to creation.

This right here is why nobody ever does anything different anymore. This is why programming has become less about actual programming knowledge and more about understanding how to use pre-built libraries and apis.

You, sir, are the reason it's no longer awesome to be a programmer. Because nobody can try anything new anymore because you slam it for breaking with convention. I'm ashamed to call myself a developer because so many "programmers" are people like you who destroy any and all creativity in this world.

By writing and posting an article it is assumed and implied the author has knowledge, skills and experience about the subject they are presenting. An article is not the place for an author to bounce ideas while learning. If you want to learn, which is what this site is all about, then ask questions in the forums, then when you have amore thorough understanding of the subject, submit an article.

I read the article (not the code) and although I generally like the idea, there are some problems related to the overall security of your solution. Please, take it as a constructive criticism that can possibly improve security of your site

1 - never ever store password on the server, I know, you encrypted it, but it can be decrypted and read on the server - BAD for you. Better is to store only salted hash and salt. Even when someone steals your database, he will not be able to read the passwords (and because users uses one password on multiple places, it's still valuable information, even when your site is down)

2 - never ever send the password through an e-mail = it's like posting it on the board when everyone can read it.

3 - it's not clear to me, how the user will retrieve it's new password from the system.

Thanks for the points pointers.
I'd like to address them if I could, and when I have time, I'll update the article to reflect:

1 - In the download, you'll find a file called Crypt.vb. In addition to providing general hashing, this file also does salting. After I read your comment I realized I probably should've put that into the article.

2 - I had thought of the standard functionality to reset a password (Forgot my password), but I'm not sure how to set that up.

1 - I see, but you salt all your passwords with the same salt value (VB code is a bit awkward for me, so correct me when I'm wrong, but I see no column for the salt in the Users table). Then, for dictionary attack, instead of SHA1(password) from list of common passwords, I need to do SHA1(password+fixedsalt) - this doesn't increase the attack complexity much.
Much better is to add a salt column and salt each password with it's own random salt. It's simple step, but it increases the attack complexity a much (because I cannot precalculate the hash tables for known weak passwords and even when the passwords of two users will be the same, I cannot take any advantage from this).

2 - well, this is always tricky - you need to make some security compromises there. When user clicks on "Forgot my password", I'd send him an e-mail with unique temporary, single use, URL to a page, where he can set new password. Once the link is used, it cannot be reused. It is also valid only for some time (as short as possible, but we need to consider the email delivery delays).

Oh I see now, I wanted to use a random salt every time, but a friend pointed out that if the salt was random, the hash would be different every time the password was encrypted, so you'd never be able to log in again.
This idea of generating and storing a random salt for every registration sounds really great to me

I also like the idea of using a temporary, single use URL for password recovery, but I'm not sure how to generate it, although an idea just popped into my head as I'm typing this.

geo_m, look forward to improvements based on your suggestions, as well as an honorable mention in the next release.

I have some free time now and I was just about to get some work done on the changes your proposed for the login system, but I'm in a bit of a quandary right now.

The idea for this login system was that values change as they need to.

So here are my problems:
1. Assuming I just allow for the user to reset their password if they forget it, how does this fit in with the "Mutating" idea?
2. How do your proposed changes make my system different/better to any login system currently available to the public?

Although it has its own problems, it's similar to what you want to achieve, if I am right. It not only changes in a time of "attack", but literally everytime.

ad 2 - well that would be difficult, if not impossible, unless you'll discover something really new in a math (eg. as Rivest, Shamir, Adleman did). I personally can only provide a implementation of already existing proven authentication scheme. Developing a really new auth. scheme requires strong math background and lot of time for public validation

Personally, I think, that the biggest problem in autentication field is not to develop new auth. schemes, but to balance security and convenience. We have pretty good algorithms on the math side, but on the other side, just forcing users to use really strong password leads to yellow stickers on the monitor - avoiding security at all

For common business related security, I'd say that uid/pwd + otp is very safe solution:

- When you use challenge-response for pwd transfer, you should avoid man-in-the-middle and password replay attacks.
- When you don't transfer the password or it's unsalted hash over the wire, you will avoid the listener just to read it an reuse it.
- Storing only the salted hashes in database will increase the security in case the DB is stolen or misused (neither db admin is able to read passwords).
- The OTP should slightly limit the possibility of social-attacks (although not completely, but it avoids the common "I'll tell you my password" or "yello sticker" problem, because you need something more than just knowing the password)

The idea of password auto-reset is a bit problematic to me, because then you need some mechanism to deliver the new password to the user.
As an attacker, I would do few fake login attempts and instead of hacking the authentication itself, I would try to break that password delivery mechanism - catch the email, sms or any other message containing the new password. It's usually much easier