diff --git a/app/src/main/java/me/impy/aegis/ScannerActivity.java b/app/src/main/java/me/impy/aegis/ScannerActivity.java index 6bd21d98..3264f972 100644 --- a/app/src/main/java/me/impy/aegis/ScannerActivity.java +++ b/app/src/main/java/me/impy/aegis/ScannerActivity.java @@ -4,6 +4,7 @@ import android.Manifest; import android.app.Activity; import android.content.pm.PackageManager; import android.support.v4.app.ActivityCompat; +import android.support.v4.util.TimeUtils; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; @@ -12,11 +13,13 @@ import android.widget.Toast; import com.google.zxing.BarcodeFormat; import com.google.zxing.Result; +import java.sql.Time; import java.util.ArrayList; import java.util.List; import me.dm7.barcodescanner.zxing.ZXingScannerView; import me.impy.aegis.crypto.KeyInfo; +import me.impy.aegis.crypto.TOTP; public class ScannerActivity extends Activity implements ZXingScannerView.ResultHandler { private ZXingScannerView mScannerView; @@ -50,6 +53,8 @@ public class ScannerActivity extends Activity implements ZXingScannerView.Result try { 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) { e.printStackTrace(); } diff --git a/app/src/main/java/me/impy/aegis/crypto/KeyInfo.java b/app/src/main/java/me/impy/aegis/crypto/KeyInfo.java index 176e796b..b648c207 100644 --- a/app/src/main/java/me/impy/aegis/crypto/KeyInfo.java +++ b/app/src/main/java/me/impy/aegis/crypto/KeyInfo.java @@ -5,14 +5,86 @@ import android.net.Uri; import me.impy.aegis.encoding.Base32; public class KeyInfo { - private String _type; - private String _label; - private byte[] _secret; - private String _issuer; - private String _algo; - private int _digits; - private long _counter; - private String _period; + private String type; + private String label; + private byte[] secret; + private String issuer; + private String algo; + private int digits; + private long counter; + 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() { @@ -26,16 +98,16 @@ public class KeyInfo { } KeyInfo info = new KeyInfo(); - info._type = url.getHost(); + info.type = url.getHost(); String secret = url.getQueryParameter("secret"); - info._secret = Base32.decode(secret); - info._issuer = url.getQueryParameter("issuer"); - info._label = url.getPath(); - info._algo = url.getQueryParameter("algorithm"); - info._period = url.getQueryParameter("period"); - 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.secret = Base32.decode(secret); + info.issuer = url.getQueryParameter("issuer"); + info.label = url.getPath(); + info.algo = url.getQueryParameter("algorithm") != null ? url.getQueryParameter("algorithm") : "HmacSHA1"; + 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.counter = url.getQueryParameter("counter") != null ? Long.getLong(url.getQueryParameter("counter")) : 0; return info; } diff --git a/app/src/main/java/me/impy/aegis/crypto/TOTP.java b/app/src/main/java/me/impy/aegis/crypto/TOTP.java index ebfb2d8c..6c5d4edd 100644 --- a/app/src/main/java/me/impy/aegis/crypto/TOTP.java +++ b/app/src/main/java/me/impy/aegis/crypto/TOTP.java @@ -85,9 +85,9 @@ public class TOTP { * @return: a numeric String in base 10 that includes * {@link truncationDigits} digits */ - public static String generateTOTP(String key, + public static String generateTOTP(byte[] key, String time, - String returnDigits) { + int returnDigits) { return generateTOTP(key, time, returnDigits, "HmacSHA1"); } @@ -101,9 +101,9 @@ public class TOTP { * @return: a numeric String in base 10 that includes * {@link truncationDigits} digits */ - public static String generateTOTP256(String key, + public static String generateTOTP256(byte[] key, String time, - String returnDigits) { + int returnDigits) { return generateTOTP(key, time, returnDigits, "HmacSHA256"); } @@ -117,9 +117,9 @@ public class TOTP { * @return: a numeric String in base 10 that includes * {@link truncationDigits} digits */ - public static String generateTOTP512(String key, + public static String generateTOTP512(byte[] key, String time, - String returnDigits) { + int returnDigits) { return generateTOTP(key, time, returnDigits, "HmacSHA512"); } @@ -134,11 +134,10 @@ public class TOTP { * @return: a numeric String in base 10 that includes * {@link truncationDigits} digits */ - public static String generateTOTP(String key, + public static String generateTOTP(byte[] key, String time, - String returnDigits, + int returnDigits, String crypto) { - int codeDigits = Integer.decode(returnDigits).intValue(); String result = null; // Using the counter @@ -149,8 +148,7 @@ public class TOTP { // Get the HEX in a Byte[] byte[] msg = hexStr2Bytes(time); - byte[] k = hexStr2Bytes(key); - byte[] hash = hmac_sha(crypto, k, msg); + byte[] hash = hmac_sha(crypto, key, msg); // put selected bytes into result int int offset = hash[hash.length - 1] & 0xf; @@ -161,10 +159,10 @@ public class TOTP { ((hash[offset + 2] & 0xff) << 8) | (hash[offset + 3] & 0xff); - int otp = binary % DIGITS_POWER[codeDigits]; + int otp = binary % DIGITS_POWER[returnDigits]; result = Integer.toString(otp); - while (result.length() < codeDigits) { + while (result.length() < returnDigits) { result = "0" + result; } return result;