Skip to content

Instantly share code, notes, and snippets.

@mormegil-cz
Created November 8, 2017 10:32
Show Gist options
  • Save mormegil-cz/d4417e498a249d13d0c030a4799fd50f to your computer and use it in GitHub Desktop.
Save mormegil-cz/d4417e498a249d13d0c030a4799fd50f to your computer and use it in GitHub Desktop.
Generátor QR kódu pro inicializaci HOTP pro datové schránky
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Generátor QR kódu pro inicializaci HOTP pro datové schránky</title>
<meta name="copyright" content="Bedřich Košata, Laboratoře CZ.NIC" />
<meta name="original-source" content="http://blog.nic.cz/2011/10/10/kouzlo-standardizovaneho-reseni/" />
</head>
<body>
<h1>Generátor QR kódu pro inicializaci HOTP pro datové schránky</h1>
<div>
<label for="name">Název klíče:</label> <input id="name" value="Datová schránka" /><br />
<label for="secret">Tajný klíč (zkopírujte do systému DS):</label> <input id="secret" size="80" /> (<a href="#" onclick="generate_random(); return false">vygenerovat náhodný</a>)
</div>
<div id="qrcode"></div>
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha256-k2WSCIexGzOj3Euiig+TlR8gA0EmPjuc79OEeY5L45g=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.qrcode/1.0/jquery.qrcode.min.js"></script>
<script>
function b32encode(s) {
/* encodes a string s to base32 and returns the encoded string */
var alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
var parts = [];
var quanta= Math.floor((s.length / 5));
var leftover = s.length % 5;
if (leftover != 0) {
for (var i = 0; i < (5-leftover); i++) { s += '\x00'; }
quanta += 1;
}
for (i = 0; i < quanta; i++) {
parts.push(alphabet.charAt(s.charCodeAt(i*5) >> 3));
parts.push(alphabet.charAt( ((s.charCodeAt(i*5) & 0x07) << 2)
| (s.charCodeAt(i*5+1) >> 6)));
parts.push(alphabet.charAt( ((s.charCodeAt(i*5+1) & 0x3F) >> 1) ));
parts.push(alphabet.charAt( ((s.charCodeAt(i*5+1) & 0x01) << 4)
| (s.charCodeAt(i*5+2) >> 4)));
parts.push(alphabet.charAt( ((s.charCodeAt(i*5+2) & 0x0F) << 1)
| (s.charCodeAt(i*5+3) >> 7)));
parts.push(alphabet.charAt( ((s.charCodeAt(i*5+3) & 0x7F) >> 2)));
parts.push(alphabet.charAt( ((s.charCodeAt(i*5+3) & 0x03) << 3)
| (s.charCodeAt(i*5+4) >> 5)));
parts.push(alphabet.charAt( ((s.charCodeAt(i*5+4) & 0x1F) )));
}
var replace = 0;
if (leftover == 1) replace = 6;
else if (leftover == 2) replace = 4;
else if (leftover == 3) replace = 3;
else if (leftover == 4) replace = 1;
for (i = 0; i < replace; i++) parts.pop();
for (i = 0; i < replace; i++) parts.push("=");
return parts.join("");
}
var last_url = null;
function update_qr() {
var allowed = '0123456789abcdefABCDEF';
var name = $("#name").val();
var key16 = $("#secret").val();
for (var i=0; i<key16.length; i++) {
if (allowed.indexOf(key16[i]) == -1) {
alert("Znak '"+key16[i]+"' není v hexadecimálním zápisu povolen!");
return;
}
}
var dec_key = b16decode(key16);
var key = b32encode(dec_key);
var url = "otpauth://hotp/"+encodeURIComponent(name)+"?secret="+key.replace(/=/g,'')+"&counter=1";
if (url == last_url)
return;
last_url = url;
$('#qrcode').empty();
if (url.length <= 118) {
$('#qrcode').qrcode({text: url,
typeNumber: 10,
width: 171,
height: 171
});
} else {
alert("Text je moc dlouhý - zkraťte jméno nebo tajný klíč.");
}
}
function generate_random() {
var chars = "0123456789ABCDEF";
var randomstring = '';
var randomarray = new Uint8Array(40);
(window.crypto || window.msCrypto).getRandomValues(randomarray);
for (var i=0; i<40; i++) {
var rnum = randomarray[i] % 16;
randomstring += chars.substring(rnum,rnum+1);
}
$("#secret").val(randomstring);
update_qr();
}
function b16decode(text) {
var result = '';
for (var i=0; i<text.length; i+=2) {
var ch = text.slice(i,i+2);
var ord = parseInt(ch, 16);
result += String.fromCharCode(ord);
}
return result;
}
$(function(){
//(function(v){v.fn.qrcode=qrcode_backup;})($);
generate_random();
var otp_timeout = null;
$('input')
.keyup(function(){
clearTimeout(otp_timeout);
otp_timeout = setTimeout(function(){
update_qr();
clearTimeout(otp_timeout);
}, 400);
})
.mouseup(function() {
$(this).keyup();
})
.change(function() {
$(this).keyup();
})
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment