mirror of
https://github.com/beemdevelopment/Aegis.git
synced 2025-04-20 13:59:14 +00:00
Generating OTP now works
This commit is contained in:
parent
8dc53357a3
commit
745e5c13b6
3 changed files with 104 additions and 29 deletions
|
@ -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…
Add table
Reference in a new issue