Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / security / cryptography

Users Hate Passwords (We're All Users): Never Memorize a Password Again

4.87/5 (29 votes)
16 Nov 2017CPOL16 min read 68.3K   487  
Complete source code that creates a solution so users never have to make up, memorize or type a password again
In this article, you will get the complete source that creates a solution so users never have to memorize, type or make up a password again. I've open-sourced the entire code base to the apps on all platforms (iOS,Android, WinForm, Web).

Update Information

Note: If this is your first time reading this article, please skip to the Introduction.

September 26, 2017

Password Requirements No Longer A Frustration

In version 1.4.1.0 (available for download at top of this article and at GitHub), I've added a valuable, frustration-relieving option to C'YaPass*. The new functionality will help you remember each site's particular password requirements. As you know, many sites require an uppercase character, a special character and/or limit the length of passwords used. Even with C'YaPass, this could be quite frustrating since it is so difficult to remember each site's requirements.

*At this point, it is only in the WinForm app, but over the coming days, I'll add it to all platforms.

Now, you can add those to the SiteKey so that when you select the SiteKey, it will set those items for you automatically. Here's a snapshot of what it looks like when you set it:

edit site requirements

Then, each time you choose that site key, the site's requirements (in this case Add UpperCase and Set MaxLength to 23) will be set for you.

site reqs selected automatically

That means you no longer have to remember what the particular site requires in your passwords.

Right-Click to Edit Previously Added Keys

The new functionality allows you to right-click to edit your previously added keys. And, if you get the new installation pkg at http://www.cyapass.com/page/get-c-yapass^, it will install seemlessly over your old version preserving all your previously added keys.

Introduction

This all started with the article I published here at CodeProject back in June, 2016:

Destroy All Passwords: Never Memorize A Password Again[^]

In that article, which has had over 300K views, I walked the reader through an idea which would allow users to create extremely strong passwords (which were SHA-256 hashes) while only requiring the user to:

  1. draw a pattern
  2. choose a site

After that article was published, I worked incessantly to write the app for a large number of platforms (Windows, iOS, Android and web) in an effort to ensure the user could generate her password no matter what platform she happened to be running.

As you will see, availability is a key issue that has to be solved for this system to be used, since passwords are not stored anywhere, but instead are generated every time.

all platforms

This article will:

  1. provide an overview of how the app solves password problems
  2. walk you through the code of the C# WinForm app
  3. discuss the benefits of this method of password management
    1. passwords are not stored anywhere (they are generated every time)
    2. user never has to type a password again
    3. user never has to memorize a password again
    4. user never has to make up a password again
  4. reveal the possible weaknesses or attack vectors of this method
  5. make a RFC (Request For Comments) - what would make the app better?
  6. announce all code (on all platforms) as Open Source projects at my github locations. Now everyone can join in, use the various apps, alter the code for their own use, share with users who (aren't devs, but) would benefit from using the app.
  7. List some challenges that need to be resolved to make the software better.
  8. One of the largest points of this article is to get you thinking about passwords and how terrible they are and how something must be done. This is my shot at doing __something__.

GitHub Contribution

Grab any of the Open Source code for any of the projects or join and contribute.

*11/16/2017

Next Articles in Series

Then, after this main article, I will write an article for the Android app and another article for the iOS app so we can look at specific challenges on each of those platforms.

Try Before You Build

If you'd like to try any or all versions of the app, you can get them very easily (without having to build them).

All of the links will take you to a landing page so you can decide if you want to download the app. Of course, the web app will simply run right in your HTML5-compatible browser.

  1. CYaPass on the App Store[^]
  2. CYaPass at Google Play[^]
  3. C'YaPass: Forget All Your Passwords | Get C'YaPass WinForm[^]
  4. C'YaPass: Forget All Your Passwords | WebApp[^]

What Might Be Interesting in this Article?

Cross-Platform Development In Real Life: The Challenges

Making the User Interface (UI) look the same across all platforms is an interesting problem.

Keeping the User Experience (UX) consistent across all platforms.

Writing the application in 4 different languages / 5 different technologies:

  1. Windows = C#
  2. Android = Java
  3. iOS = Swift
  4. Web = HTML5 (JavaScript / CSS)
  5. Windows UWA = C# / WPF (Windows Presentation Foundation)

The main challenge of the project is:

The Challenge:
The same password value must be regenerated on every platform when the user selects the same site key and draws the same pattern.

Since the passwords are generated every time and are not stored anywhere, the challenge is that the algorithm has to be duplicated on all platforms so that the original password is generated, i.e., - If the user were unable to reproduce the same password on each platform, the software would be useless since the user would find he couldn't log into his target site.

I believe you will find that seeing this carried out in the software across platforms is an interesting point of the project.

C# to Java Conversion, Easier than C# to UWA (WPF) Conversion

I wrote the original app as a WinForm app first (since I have the most experience there and the tooling is quite good). When I went to convert the code to Android, it was amazingly easy and I was able to rewrite the app in only a couple of days in Java.

In contrast, the conversion to a Universal Windows App(UWA) was far more difficult which is why I still don't have a complete official version released. Now that I'm releasing all of the code to Open Source, I will add the incomplete UWA project to a Github repository also.

The Beauty and Power of Real OOP

One of the coolest things was to actually see OOP (Object Oriented Programming) help solve problems. As we inspect the code, you will see that I have the same domain objects (Classes) implemented on all platforms (iOS, Android, Windows, Web).

Real ReUse

For example, I created a Class named Segment in the WinForm app in C#. I needed that same class in the Android app, but of course that code is written in Java. Since true OOP means that your program is broken down into components and since Objects contain their own data and functionality, it meant that all I needed to do was convert the syntax of the basic Segment object to Java syntax. That was true for all of my domain objects. That's true reuse.

Of course, you will see all the same classes reproduced in Swift, JavaScript, C# and Java. It's quite interesting.

How Does CYaPass Attempt to Solve the Password Problem?

Actually, to talk about how we solve the password problem, we need to first talk about what the password problem is. In actuality, the password problem is a number of things:

  1. a password must be available to its owner at all times (all platforms) - any time an owner needs to log into target site
  2. a password must not be available to anyone other than its owner at any time
  3. a password must not have to be memorized (known) by its owner
  4. a password must never be stored anywhere (not saved in a file, written down in a notebook, etc.)
  5. a password must not have to be typed by its owner
  6. a password must not have to be created by its owner
  7. a password must be cryptographically strong

That's not a bad list of requirements to set us on our way and which we can use to measure the validity of the solution that I provide in the CYaPass app.

How the App Helps Solve Password Problems

What we need here is an analogy and I just so happen to have one.

Analogy: Super Smart Friend with a Great Memory

Imagine you have a friend you trust completely and who has a perfect memory. This friend is capable of memorizing an unlimited number of 64 character strings. He can generate these any time you need one.

Whenever you visit a new site and have to create a new password, you call him up and say, "Hey, can you give me 64 random string made up of only numbers and letters and remember that I will use it for my First Bank password?"

"Sure," your friend says and then he starts reciting it for you, "7625b39b9ceaab94afd2b6b887d0577a79b68dcaade97df85bcf5e80de16c35c".

Now, any time you need the password, you just call up your trusted friend and log in to your First Bank account.

Inaccessible

It's that easy. The great thing is that your password is not written down anywhere or saved in any file. That just means, it is not accessible to hackers.

Very Strong

Your password is also very strong because it is extremely long. If you test it at the Kaspersky site I mentioned earlier, you will find that it will tell you that it would take over 10,000 centuries to brute-force hack it.

Very Random

It's also completely random so no one could ever just simply guess it as they might be able to by sticking a bunch of words together. The chances of someone writing a program which would be able to consistently regenerate the same random string that your friend gave you are infinitesimal.

Reproducible

It's completely reproducible (as long as your friend is alive and available), since all you have to do is call your friend and he will tell you the password again.

The reason you employ your friend for this help is because he is reliable and helpful and it allows you to offload this work to your friend. That frees you up so you don't have to think about passwords any more.

That is why we are creating this software for the user -- so he doesn't have to think about passwords any more.

Your Friend Has Intelligence

Our software implementation is just a bit different because your friend has intelligence which allows him to create 64 character random strings. We have to build that "intelligence" into our system.

What C'YaPass Really Does

Just like your friend, all C'YaPass really does is:

  1. provide you with unique random 64 character strings (when you need a new password)
  2. regenerate your original random 64 character string (when you need to log in again)

The user will use these random 64 character strings as her passwords at each of the sites where she needs to login.

The reason this will be valuable to the user is because we know that users:

  1. create weak passwords
  2. forget their passwords
  3. store their passwords in locations that are accessible to others (spreadsheets, sticky note on bottom of keyboard, notebook, etc.)

Special Characters, UpperCase, Length

Of course, because most web sites are clueless about what makes good passwords (longer is stronger), they often create bad requirements (add special chars, uppercase, etc.) so CYaPass helps by allowing users to add these items also. Keep in mind that it manages to do this in the code on every platform so that the user's password will always match.

C'YaPass Removes the Burden from the User

C'YaPass removes the burden of memorizing and managing passwords from the user. The difference between C'YaPass and your friend is that the human friend has intelligence which he uses to create random 64 character strings. In our case, we need to build some kind of algorithm that will allow C'YaPass to do that for the user.

Most of that work has been done for us by the SHA-256 Hash Algorithm and we are going to leverage it.

Hashing or One-Way Encryption

If you've read my previous article, then you know how this works so I'll just summarize it here.

To generate a password, the user must:

  1. select a site key (keep in mind a site key is any string the user decides to add to the list in order to remember what site or login she is using the password for. This allows the user to have multiple site keys (one for each login) while using one pattern.)
  2. draw a pattern on the grid which contains at least one segment (two points)

We'll use the following site key (supersite) and pattern shown in this image:

supersite example

Here's how the app generates the password shown in the previous image:

  1. gets the site key and stores in a byte buffer
  2. calculates the value from the pattern which the user has drawn on the grid
  3. prepends generated value as bytes to the site key byte buffer (to salt the site key value)
  4. generates the SHA-256 hash of the bytes -- our cleartext string for the one shown in the previous image would looke like "4088supersite"
  5. displays the password (SHA-256 hash of "4088supersite") in the text box for the user
  6. copies the password to the user's clipboard for easy use (can paste into web site password box).

Did Your Mind Just Explode?

Did that seem too simple? Do you feel like there should've been something more? Some readers of my original article just lost their minds when they thought this through. "It can't be that simple," they yelled. "It can't be!"

However, remember, all the app does is...

 
...generate extremely long, cryptographically strong passwords in a reproducible manner.

It just so happens that any SHA-256 hash could make a really good password, because it is so random (cryptographically strong) that it could never be guessed.

We are leveraging the power of the SHA-256 Hash Algorithm.

Here's what the code looks like in the Windows Form app:

C#
private void ComputeHashBytes()
        {
            var m256 = SHA256Managed.Create();
            var patternBytes = 
                System.Text.Encoding.UTF8.GetBytes(us.PointValue.ToString());
            var selItemText = SiteListBox.SelectedItem.ToString();
            var siteBytes = System.Text.Encoding.UTF8.GetBytes(selItemText);
            byte[] allBytes = null;

            allBytes = new byte[patternBytes.Length + siteBytes.Length];
            patternBytes.CopyTo(allBytes, 0);
            siteBytes.CopyTo(allBytes, patternBytes.Length);

            byte[] hashBytes = m256.ComputeHash(allBytes);
            pwdBuilder = new StringBuilder();
            // create a string of hex values for output
            foreach (byte b in hashBytes) { pwdBuilder.AppendFormat("{0:x2}", b); }
        }

You can see that I simply use the C# provided Cryptography library to create a SHA256 hash.

The only interesting part really is the us.PointValue.ToString() (which I've bolded in the previous code example.

The us part is the UserPath object that manages the PointValue calculation as the user clicks on each of the posts in the grid. I originally had that named a UserShape but changed it. As I mentioned earlier, I was racing to get this app created and make it usable as fast as I could.

When you take a look at the UserPath class, you'll see it is quite simple but does a bit of work to ensure the user can never draw a Segment more than once. For example, the user can keep clicking the same two Posts over and over and change the value. Instead the code ensures that a line between two posts can only occur one time.

C#
 class UserPath
  {
    public List<Point> allPoints = new List<Point>();
    public HashSet<Segment> allSegments = new HashSet<Segment>();
    private Point currentPoint;
    public int PointValue;
    private int previousPostValue;

    public void append(Point currentPoint, int postValue)
    {
       this.currentPoint = currentPoint;
            
       if (allPoints.Count >= 1)
       {
           if (allPoints[allPoints.Count - 1].X == currentPoint.X && 
                         allPoints[allPoints.Count - 1].Y == currentPoint.Y)
           {
               // user clicked the same point twice
               return;
           }
           allSegments.Add(new Segment(allPoints[allPoints.Count - 1], 
                           currentPoint, postValue + previousPostValue));
       }
       allPoints.Add(currentPoint);
       previousPostValue = postValue;
    }

   public void CalculateGeometricValue()
   {
       this.PointValue = 0;
       foreach (Segment s in allSegments)
       {
          this.PointValue += s.PointValue;
         }
       }
   }
}

This class keeps track of the Segments, ensures they are never added more than once and calculates the Post value in a way that only one pattern can calculate a particular value. You can't calculate the same value using two different paths. That's important just for the randomness of the salt value that is added to our site key when we generate the final hash password for the user.

Now, for fun, let's take a look at the Swift code (for iPhone/iPad) where I reproduced this same functionality.

Swift
class UserPath {
    
    var allPoints :[CGPoint]! = []
    var allSegments : Set<Segment> = Set<Segment>()
    var PostPoints : String!
    var PostValue : Int!
    var currentPoint : CGPoint = CGPoint.zero
    var previousPostValue : Int!
    
    init(){
        self.PostValue = 0
    }
    
    func append(currentPoint:CGPoint, postValue : Int) {
        self.currentPoint = currentPoint
        
        if allPoints.count >= 1{
            if (allPoints[allPoints.count-1].x == currentPoint.x && 
                          allPoints[allPoints.count - 1].y == currentPoint.y){
                return;
            }
            allSegments.insert(Segment(begin: allPoints[allPoints.count - 1], 
               end: currentPoint, pointValue: postValue + previousPostValue))
        }
        
        allPoints.append(currentPoint)
        previousPostValue = postValue;
    }
    
    func CalculateGeometricSaltValue(){
        self.PostValue = 0;
        for s in allSegments{
            self.PostValue = self.PostValue + s.PointValue
        }
    }
}

You can see that the two are very similar and this made producing the app on multiple platforms a bit easier since I could work on each class separately and test them as I went.

Challenges that Still Need to be Solved

Resetting Passwsords

This is a challenge since you need your old password and your new password. If you're changing your password by changing your drawn pattern, you'll have to switch back to your original drawn pattern to get the old one. Then you'd have to draw your new one to generate your new password.

Sharing Site Keys

Allow user to save site keys across devices so she doesn't have to type them in on every device.

For those of you who think the app should be more secure, then you can just

Ability to Sort Site Keys

Allow user to sort the site keys however she wishes (alphabetically, most used, etc.) and save the order as a preference.

Don't Allow User To Add A Duplicate Key

If the user attempts to enter a duplicate key, instead simply highlight the key for him.

Odd Intermittent Bug WinForm Clipboard

There is an intermittent bug that throws an exception when copying the password to the clipboard. Not sure why this occurs, but if you ignore it and allow the program to copy to the clipboard again, then it will work fine. It only happens in rare instances and that's why this bug is so odd. It's as if Windows makes the clipboard unavailable at times.

WebApp: Needs Auto-copy to User's Clipboard

Advanced Discussions

Humans can Create Uncrackable Passwords

Isn't it interesting that some made-up passwords can be very strong -- basically uncrackable?

You could make up a very strong password that is memorable to you. For example, if you check the following password, $1im5h4dy1iv3s, (at Secure Password Checker — Kaspersky Lab[^]), it will tell you that it will take 800 years to brute-force hack the password.

So, the idea is not that you cannot create a strong password on your own, but rather that you need so many of them, it becomes burdensome to memorize them all. Plus, you will invariably need to change your passwords and then you have even more to remember (along with old ones you need to forget).

Yet Another Salt: Virtually UnCrackable

We could allow the user to add a secret value that only she knows to each of her devices (for example, 382) and that would add an additional salt she would only have to add one time, but which would literally make it impossible for hackers to guess. Since there'd be a third salt that would make the virtually uncrackable because there would be too many combinations.

Try the Code, Use It and Join the Github and the Discussion

I hope you'll try the code. Get apps or the source and try it out. I use it for all of my passwords and it is fantastic because I don't have to think about passwords any more.

I've included the WinForm C# app source at the top of the article for convenience but it is the same source that is available via Github. Also, yes you will find some extra methods in there that are no longer used. This too was part of the rush to get the app working.

Much More Information About the App

There's way more information about the app at my web site: C'YaPass: Forget All Your Passwords [^].

There are also videos where you can see it in action. I think the best one is where I show it being used on Windows and then on iPhone where it generates the same password on my About page: C'YaPass: Forget All Your Passwords | About[^]

History

  • 23rd August, 2017: First release of this article and official announcement of all C'YaPass code available as Open Source

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)