tokenizer

A quick and dirty password key derivation tool powered by Crypto-JS.

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/core.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/x64-core.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/enc-base64.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/hmac.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/sha1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/sha256.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/sha512.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/pbkdf2.min.js"></script>
<!doctype html>
<html lang="en">
<head>

	<title>=T0k3n!z3R=</title>
	<meta charset="utf-8">

</head>
<body>
<h1>=T0k3n!z3R=</h1>
<form>
<hr/>
	<table>	

		<tr><td colspan="2"><h3>Private &amp; secret</h3></td></tr>

		<tr>
			<td>User: <i>(your name)</i></td>
			<td><input title="Your name" type="text" id="user-name" size="30" placeholder="Jones Smith" /></td>
		</tr>

		<tr>
			<td>Password: <i>(master seed or passphrase)</i></td>
			<td><input title="Master password" type="password" id="master-key" size="30" placeholder="••••• ••••• •••••" /></td>
		</tr>

		<tr><td colspan="2"><h3>Public &amp; known</h3></td></tr>

		<tr>
			<td>Login: <i>(e-mail or alias or pseudonym)</i></td>
			<td><input title="User login" type="text" id="user-login" size="30" placeholder="jsmith123 / jones.smith@email.com" /></td>
		</tr>

		<tr>
			<td>Server: <i>(domain or hostname)</i></td>
			<td><input title="Domain name" type="text" id="host-server" size="30" placeholder="website.com"/></td>
		</tr>

		<tr><td colspan="2">&nbsp;</td></tr>

		<tr>
			<td><input type="button" value="Get my token" onclick="getToken()" /> <i>(may take a while...)</i></td>
			<td><b><span title="Your credential" id="token">&infin;</span></b><br/></td>
		</tr>

		<tr><td...

CSS

i { font-size: 0.8em; }
h1 { font-family: monospace; }

JavaScript

"use strict";

function tokenizer(auth, host, key)
{
	var pbkdf2 = CryptoJS.PBKDF2(auth, key, {hasher: CryptoJS.algo.SHA256, keySize: 512/32, iterations: 300000});
	var hmac512 = CryptoJS.HmacSHA512(host, pbkdf2.toString());
	return CryptoJS.SHA1(hmac512).toString(CryptoJS.enc.Base64); 
}

function token2pin(token_b64)
{
	var hex_data = CryptoJS.enc.Base64.parse(token_b64).toString();
	var hex_word = hex_data.match(/(.{1,6})/g);
	var hexpin = parseInt(hex_word.shift(), 16);

	for (var i=0; i<hex_word.length; i++) hexpin = (hexpin ^ parseInt(hex_word[i], 16));

	return token_b64.substring(token_b64.length - 4) + hexpin;
}

function getToken()
{
	document.getElementById("token").textContent = '';

	var user = document.getElementById("user-name").value.trim();
	var login = document.getElementById("user-login").value.trim();
	var server = document.getElementById("host-server").value.trim();
	var password = document.getElementById("master-key").value.trim();

	var host = CryptoJS.SHA512(login + server).toString();
	var auth = CryptoJS.SHA512(user + host).toString();
	var key = CryptoJS.SHA512(password).toString();

	var token = tokenizer(auth, host, key);

	document.getElementById("token").textContent = '!' + token;			
	document.getElementById("pin-token").textContent = token2pin(token);
}