Generating OTP now works

pull/41/head
Michael Schättgen 9 years ago
parent 8dc53357a3
commit 745e5c13b6

@ -4,6 +4,7 @@ import android.Manifest;
import android.app.Activity; import android.app.Activity;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.support.v4.app.ActivityCompat; import android.support.v4.app.ActivityCompat;
import android.support.v4.util.TimeUtils;
import android.support.v7.app.AppCompatActivity; import android.support.v7.app.AppCompatActivity;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log; import android.util.Log;
@ -12,11 +13,13 @@ import android.widget.Toast;
import com.google.zxing.BarcodeFormat; import com.google.zxing.BarcodeFormat;
import com.google.zxing.Result; import com.google.zxing.Result;
import java.sql.Time;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import me.dm7.barcodescanner.zxing.ZXingScannerView; import me.dm7.barcodescanner.zxing.ZXingScannerView;
import me.impy.aegis.crypto.KeyInfo; import me.impy.aegis.crypto.KeyInfo;
import me.impy.aegis.crypto.TOTP;
public class ScannerActivity extends Activity implements ZXingScannerView.ResultHandler { public class ScannerActivity extends Activity implements ZXingScannerView.ResultHandler {
private ZXingScannerView mScannerView; private ZXingScannerView mScannerView;
@ -50,6 +53,8 @@ public class ScannerActivity extends Activity implements ZXingScannerView.Result
try { try {
KeyInfo info = KeyInfo.FromURL(rawResult.getText()); KeyInfo info = KeyInfo.FromURL(rawResult.getText());
String nowTimeString = (Long.toHexString(System.currentTimeMillis() / 1000 / info.getPeriod()));
Toast.makeText(this, TOTP.generateTOTP(info.getSecret(), nowTimeString, info.getDigits(), info.getAlgo()), Toast.LENGTH_LONG).show();
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }

@ -5,14 +5,86 @@ import android.net.Uri;
import me.impy.aegis.encoding.Base32; import me.impy.aegis.encoding.Base32;
public class KeyInfo { public class KeyInfo {
private String _type; private String type;
private String _label; private String label;
private byte[] _secret; private byte[] secret;
private String _issuer; private String issuer;
private String _algo; private String algo;
private int _digits; private int digits;
private long _counter; private long counter;
private String _period; private int period;
public String getType() {
return type;
}
public KeyInfo setType(String type) {
this.type = type;
return this;
}
public String getLabel() {
return label;
}
public KeyInfo setLabel(String label) {
this.label = label;
return this;
}
public byte[] getSecret() {
return secret;
}
public KeyInfo setSecret(byte[] secret) {
this.secret = secret;
return this;
}
public String getIssuer() {
return issuer;
}
public KeyInfo setIssuer(String issuer) {
this.issuer = issuer;
return this;
}
public String getAlgo() {
return algo;
}
public KeyInfo setAlgo(String algo) {
this.algo = algo;
return this;
}
public int getDigits() {
return digits;
}
public KeyInfo setDigits(int digits) {
this.digits = digits;
return this;
}
public long getCounter() {
return counter;
}
public KeyInfo setCounter(long counter) {
this.counter = counter;
return this;
}
public int getPeriod() {
return period;
}
public KeyInfo setPeriod(int period) {
this.period = period;
return this;
}
private KeyInfo() { private KeyInfo() {
@ -26,16 +98,16 @@ public class KeyInfo {
} }
KeyInfo info = new KeyInfo(); KeyInfo info = new KeyInfo();
info._type = url.getHost(); info.type = url.getHost();
String secret = url.getQueryParameter("secret"); String secret = url.getQueryParameter("secret");
info._secret = Base32.decode(secret); info.secret = Base32.decode(secret);
info._issuer = url.getQueryParameter("issuer"); info.issuer = url.getQueryParameter("issuer");
info._label = url.getPath(); info.label = url.getPath();
info._algo = url.getQueryParameter("algorithm"); info.algo = url.getQueryParameter("algorithm") != null ? url.getQueryParameter("algorithm") : "HmacSHA1";
info._period = url.getQueryParameter("period"); info.period = url.getQueryParameter("period") != null ? Integer.getInteger(url.getQueryParameter("period")) : 30;
info._digits = url.getQueryParameter("digits") != null ? Integer.getInteger(url.getQueryParameter("digits")) : 6; info.digits = url.getQueryParameter("digits") != null ? Integer.getInteger(url.getQueryParameter("digits")) : 6;
info._counter = url.getQueryParameter("counter") != null ? Long.getLong(url.getQueryParameter("counter")) : 0; info.counter = url.getQueryParameter("counter") != null ? Long.getLong(url.getQueryParameter("counter")) : 0;
return info; return info;
} }

@ -85,9 +85,9 @@ public class TOTP {
* @return: a numeric String in base 10 that includes * @return: a numeric String in base 10 that includes
* {@link truncationDigits} digits * {@link truncationDigits} digits
*/ */
public static String generateTOTP(String key, public static String generateTOTP(byte[] key,
String time, String time,
String returnDigits) { int returnDigits) {
return generateTOTP(key, time, returnDigits, "HmacSHA1"); return generateTOTP(key, time, returnDigits, "HmacSHA1");
} }
@ -101,9 +101,9 @@ public class TOTP {
* @return: a numeric String in base 10 that includes * @return: a numeric String in base 10 that includes
* {@link truncationDigits} digits * {@link truncationDigits} digits
*/ */
public static String generateTOTP256(String key, public static String generateTOTP256(byte[] key,
String time, String time,
String returnDigits) { int returnDigits) {
return generateTOTP(key, time, returnDigits, "HmacSHA256"); return generateTOTP(key, time, returnDigits, "HmacSHA256");
} }
@ -117,9 +117,9 @@ public class TOTP {
* @return: a numeric String in base 10 that includes * @return: a numeric String in base 10 that includes
* {@link truncationDigits} digits * {@link truncationDigits} digits
*/ */
public static String generateTOTP512(String key, public static String generateTOTP512(byte[] key,
String time, String time,
String returnDigits) { int returnDigits) {
return generateTOTP(key, time, returnDigits, "HmacSHA512"); return generateTOTP(key, time, returnDigits, "HmacSHA512");
} }
@ -134,11 +134,10 @@ public class TOTP {
* @return: a numeric String in base 10 that includes * @return: a numeric String in base 10 that includes
* {@link truncationDigits} digits * {@link truncationDigits} digits
*/ */
public static String generateTOTP(String key, public static String generateTOTP(byte[] key,
String time, String time,
String returnDigits, int returnDigits,
String crypto) { String crypto) {
int codeDigits = Integer.decode(returnDigits).intValue();
String result = null; String result = null;
// Using the counter // Using the counter
@ -149,8 +148,7 @@ public class TOTP {
// Get the HEX in a Byte[] // Get the HEX in a Byte[]
byte[] msg = hexStr2Bytes(time); byte[] msg = hexStr2Bytes(time);
byte[] k = hexStr2Bytes(key); byte[] hash = hmac_sha(crypto, key, msg);
byte[] hash = hmac_sha(crypto, k, msg);
// put selected bytes into result int // put selected bytes into result int
int offset = hash[hash.length - 1] & 0xf; int offset = hash[hash.length - 1] & 0xf;
@ -161,10 +159,10 @@ public class TOTP {
((hash[offset + 2] & 0xff) << 8) | ((hash[offset + 2] & 0xff) << 8) |
(hash[offset + 3] & 0xff); (hash[offset + 3] & 0xff);
int otp = binary % DIGITS_POWER[codeDigits]; int otp = binary % DIGITS_POWER[returnDigits];
result = Integer.toString(otp); result = Integer.toString(otp);
while (result.length() < codeDigits) { while (result.length() < returnDigits) {
result = "0" + result; result = "0" + result;
} }
return result; return result;

Loading…
Cancel
Save