Many small applications need to store user credentials, but it’s hard to create a good username/password infrastructure. What if you could just use a small XML file with credentials that don’t actually stores the password, but just a hash and some salt.

For a small cloud project I ended up creating such a solution. This blog explains how to generate the credentials that can be stored in the XML. The aim is to make a solution that works on the client using JavaScript.

Program

Techniques

In this solution we use the following techniques:

  • Hashing – a hash is a mathematical function that will turn a plain-text into a huge number. If one of the letters in the plain-text is changed, the hash changes. If a user gives us a password, we can hash that password and compare it to the hash we have. Not storing the password makes your user data more secure.
  • Salt – some attackers will use a rainbow table attack. They have huge table with plain-texts and their hashes. To mitigate this attack, we’ll generate salt and add it to the plain-text that will be hashed. In our case the plain-text will be 40 characters long. It’s hard to generate a rainbow table for it.
  • SHA256 – is the hash function we will use. It generates a 32-bit hash.

Frameworks

Never code what you don’t need. I used the following JavaScript frameworks to make coding easier:

  • JQuery – always makes life easier
  • Knockout JS – a framework to bind a model to the DOM
  • Crypto-JS – a small solution that helps to generate SHA256 hashes.

I’m using a CDN to get the includes:

<script type="text/javascript" src="//code.jquery.com/jquery-compat-git.js"></script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/knockout/3.3.0/knockout-min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/components/core.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/components/sha256-min.js"></script>

A string randomizer

We need a randomizer to create salt and generate passwords. We’ll be using the following function:

var randomString = function (length, nonAlpha) {
	var text = "";
	var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

	if (nonAlpha) {
		possible += '[email protected]#$%^*()/*`~={}|\][;:,./?';
	}

	for (var i = 0; i < length; i++) {
		text += possible.charAt(Math.floor(Math.random() * possible.length));
	}

	return text;
}

If we use this function to generate salt, we should generate longer salt, because the entropy of the JavaScript generator isn’t that great.

A model

Let’s create a model . It will be the heart of the application:

var PasswordModel = function () {

	var _this = this;
	this.userName = ko.observable('');
	this.password = ko.observable('');
	this.roles = ko.observable('');

	this.salt = ko.computed(function () {
		//generate new salt on password/username update
		var u = _this.userName();
		var p = _this.password();
		return randomString(24, true);
	});

	this.hash = ko.computed(function () {
		var h = _this.salt() + _this.password();
		return CryptoJS.SHA256(h);
	});

	this.xml = ko.computed(function () {

		var xml = $('<user />');
		xml.attr('name', _this.userName());
		xml.attr('roles', _this.roles());
		xml.attr('salt', _this.salt());
		xml.attr('hash', _this.hash());

		return xml.wrap('<div/>').parent().html();
	});

	//generate a new alpha-numeric password
	this.generateNewPassword = function () {
		var password = randomString(16, false);
		_this.password(password);
	};

	this.generateNewPassword();
}

A user interface

Next we’ll need to create a simple user interface and let Knockout do the rest:

 <div class="row">
      <label>
         <span>Username:</span>
         <input data-bind="value: userName, valueUpdate: 'afterkeydown'" class="value" autocomplete="off" />
      </label>
   </div>
   <div class="row">
      <label>
         <span>Password:</span>
         <input data-bind="value: password, valueUpdate: 'afterkeydown'" class="value" autocomplete="off" />
      </label>
   </div>
   <div class="row">
      <label>
         <span />
         <button type="checkbox" data-bind="click: generateNewPassword">Generate new password</button>
      </label>
   </div>
   <div class="row">
      <label>
         <span>Roles:</span>
         <input data-bind="value: roles, valueUpdate: 'afterkeydown'" class="value" />
      </label>
   </div>
   <div class="row">
      <label>
         <span>XML:</span>
         <code data-bind="text: xml" class="value" />
      </label>
   </div>

Knockout binding:

$(document).ready(function () {
	var model = new Model();
	ko.applyBindings(model);
});

Wrap-up

So that’s it. It’s quite easy to make and host yourself, check GitHub. But you’re always welcome to use my generator: KeesTalksTech Password Generator.