Initial version

pull/1/head
Viljo Viitanen 2015-09-16 00:05:07 +03:00
rodzic eda8fb60b4
commit b4cf55f299
2 zmienionych plików z 129 dodań i 0 usunięć

124
export.html 100644
Wyświetl plik

@ -0,0 +1,124 @@
<!--
* Based on php code by Philip Sharp, converted to javascript by Viljo Viitanen
*
* FreeOTP Decoder Javascript
*
* Copyright 2015 Philip Sharp, Viljo Viitanen
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
NOTE: adb backup files can be extracted with the following one-liner on linux:
dd if=backup.ab bs=1 skip=24 | python -c "import zlib,sys;sys.stdout.write(zlib.decompress(sys.stdin.read()))" | tar -xvf -
-->
<style>
p{margin:50px}
div{margin:10px}
</style>
<a href="https://github.com/viljoviitanen/freeotp-export">Instructions at github</a>
<br>
<input id="file" type="file">
<script src="https://cdn.rawgit.com/viljoviitanen/qrcodejs/master/qrcode.min.js"></script>
<script type="text/javascript">
//ported from original PHP function
/**
* Convert stored secret into otpauth URI parameter
*
* Port of encodeInternal() method from Google Authenticator via FreeOTP
* @link https://fedorahosted.org/freeotp/browser/android/app/src/main/java/com/google/android/apps/authenticator/Base32String.java
*
* @param array $data Internal representation of the secret as byte array
* @return string Secret as Base32 encode string
*/
function encodeSecretBytes(data) {
DIGITS = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','2','3','4','5','6','7','']; // 32 chars
SHIFT = 5; // trailing zeros in binary representation of the size of the alphabet
MASK = 31; // one less than size of alphabet
// SHIFT is the number of bits per output character, so the length of the
// output is the length of the input multiplied by 8/SHIFT, rounded up.
if (data.length >= (1 << 28)) {
alert('Bad Secret');
}
outputLength = (data.length * 8 + SHIFT - 1) / SHIFT;
result = '';
buffer = data[0];
next = 1;
bitsLeft = 8;
while (bitsLeft > 0 || next < data.length) {
if (bitsLeft < SHIFT) {
if (next < data.length) {
buffer <<= 8;
buffer |= (data[next++] & 0xff);
bitsLeft += 8;
} else {
pad = SHIFT - bitsLeft;
buffer <<= pad;
bitsLeft += pad;
}
}
index = MASK & (buffer >> (bitsLeft - SHIFT));
bitsLeft -= SHIFT;
result += DIGITS[index];
}
return result;
}
//small helper function
function querydata(p)
{
var r= [];
for (var d in p) {
r.push(encodeURIComponent(d)+"="+encodeURIComponent(p[d]));
}
return r.join("&");
}
var reader = new FileReader();
reader.onload = function(event) {
parser = new DOMParser();
xml=parser.parseFromString(event.target.result, "text/xml");
s=xml.getElementsByTagName('string');
if (s.length==0) {
alert('Cannot parse the file');
}
for (var i = 0, len = s.length; i < len; i++) {
name=s[i].attributes['name'].value;
if (name == 'tokenOrder') {
continue;
}
j=JSON.parse(s[i].textContent);
param={
'secret' : encodeSecretBytes(j['secret']),
'issuer' : j['issuerInt'] ? j['issuerInt'] : j['issuerExt'],
'algorithm' : j['algo'],
'digits' : j['digits'],
'period' : j['period'],
}
label = (j['issuerExt']) ? j['issuerExt']+':'+j['label'] : j['label'];
uri='otpauth://'+j['type'].toLowerCase()+'/'+encodeURIComponent(label)+'/?'+querydata(param);
console.log(uri);
document.getElementById("file").insertAdjacentHTML('afterend', '<p><div>'+name+'</div><div id="'+i+'"></div>' );
new QRCode(document.getElementById(i),uri);
}
}
document.getElementById("file").onchange=function() {
reader.readAsText(this.files[0]);
};
</script>

Wyświetl plik

@ -0,0 +1,5 @@
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
<string name="Example:alice@google.com">{&quot;algo&quot;:&quot;SHA1&quot;,&quot;type&quot;:&quot;TOTP&quot;,&quot;secret&quot;:[72,101,108,108,111,33,-34,-83,-66,-17],&quot;issuerExt&quot;:&quot;Example&quot;,&quot;issuerInt&quot;:&quot;Example&quot;,&quot;label&quot;:&quot;alice@google.com&quot;,&quot;counter&quot;:0,&quot;digits&quot;:6,&quot;period&quot;:30}</string>
<string name="tokenOrder">[&quot;Example:alice@google.com&quot;]</string>
</map>