From 1dd5f893da8c16638efa3f79b50338c1ad59bd9d Mon Sep 17 00:00:00 2001 From: Alexander Bakker Date: Sun, 31 Mar 2019 22:15:03 +0200 Subject: [PATCH] Add support for Steam OTP --- .../aegis/crypto/otp/HOTP.java | 13 +-- .../beemdevelopment/aegis/crypto/otp/OTP.java | 50 ++++++++++++ .../aegis/crypto/otp/TOTP.java | 4 +- .../aegis/importers/DatabaseAppImporter.java | 1 + .../aegis/importers/SteamAppImporter.java | 80 +++++++++++++++++++ .../beemdevelopment/aegis/otp/HotpInfo.java | 8 +- .../beemdevelopment/aegis/otp/OtpInfo.java | 16 ++-- .../beemdevelopment/aegis/otp/SteamInfo.java | 34 ++++++++ .../beemdevelopment/aegis/otp/TotpInfo.java | 8 +- .../aegis/ui/EditEntryActivity.java | 34 ++++---- .../aegis/ui/MainActivity.java | 3 +- .../aegis/ui/PreferencesFragment.java | 5 -- .../aegis/ui/views/EntryHolder.java | 18 ++++- .../aegis/ui/views/EntryListView.java | 3 - app/src/main/res/values-ru/strings.xml | 2 +- app/src/main/res/values/strings.xml | 1 + .../com/beemdevelopment/aegis/HOTPTest.java | 5 +- .../com/beemdevelopment/aegis/TOTPTest.java | 5 +- 18 files changed, 234 insertions(+), 56 deletions(-) create mode 100644 app/src/main/java/com/beemdevelopment/aegis/crypto/otp/OTP.java create mode 100644 app/src/main/java/com/beemdevelopment/aegis/importers/SteamAppImporter.java create mode 100644 app/src/main/java/com/beemdevelopment/aegis/otp/SteamInfo.java diff --git a/app/src/main/java/com/beemdevelopment/aegis/crypto/otp/HOTP.java b/app/src/main/java/com/beemdevelopment/aegis/crypto/otp/HOTP.java index 1e5707a4..9e4f45d8 100644 --- a/app/src/main/java/com/beemdevelopment/aegis/crypto/otp/HOTP.java +++ b/app/src/main/java/com/beemdevelopment/aegis/crypto/otp/HOTP.java @@ -12,7 +12,7 @@ public class HOTP { private HOTP() { } - public static String generateOTP(byte[] secret, String algo, int digits, long counter) + public static OTP generateOTP(byte[] secret, String algo, int digits, long counter) throws NoSuchAlgorithmException, InvalidKeyException { SecretKeySpec key = new SecretKeySpec(secret, "RAW"); @@ -30,18 +30,11 @@ public class HOTP { // truncate hash to get the HTOP value // http://tools.ietf.org/html/rfc4226#section-5.4 int offset = hash[hash.length - 1] & 0xf; - long bin = ((hash[offset] & 0x7f) << 24) + int otp = ((hash[offset] & 0x7f) << 24) | ((hash[offset + 1] & 0xff) << 16) | ((hash[offset + 2] & 0xff) << 8) | (hash[offset + 3] & 0xff); - long otp = bin % (long) Math.pow(10, digits); - // prepend zeroes if needed - StringBuilder res = new StringBuilder(Long.toString(otp)); - while (res.length() < digits) { - res.insert(0, "0"); - } - - return res.toString(); + return new OTP(otp, digits); } } diff --git a/app/src/main/java/com/beemdevelopment/aegis/crypto/otp/OTP.java b/app/src/main/java/com/beemdevelopment/aegis/crypto/otp/OTP.java new file mode 100644 index 00000000..868074f9 --- /dev/null +++ b/app/src/main/java/com/beemdevelopment/aegis/crypto/otp/OTP.java @@ -0,0 +1,50 @@ +package com.beemdevelopment.aegis.crypto.otp; + +import androidx.annotation.NonNull; + +public class OTP { + private static final String STEAM_ALPHABET = "23456789BCDFGHJKMNPQRTVWXY"; + + private int _code; + private int _digits; + + public OTP(int code, int digits) { + _code = code; + _digits = digits; + } + + public int getCode() { + return _code; + } + + public int getDigits() { + return _digits; + } + + @NonNull + @Override + public String toString() { + int code = _code % (int) Math.pow(10, _digits); + + // prepend zeroes if needed + StringBuilder res = new StringBuilder(Long.toString(code)); + while (res.length() < _digits) { + res.insert(0, "0"); + } + + return res.toString(); + } + + public String toSteamString() { + int code = _code; + StringBuilder res = new StringBuilder(); + + for (int i = 0; i < _digits; i++) { + char c = STEAM_ALPHABET.charAt(code % STEAM_ALPHABET.length()); + res.append(c); + code /= STEAM_ALPHABET.length(); + } + + return res.toString(); + } +} diff --git a/app/src/main/java/com/beemdevelopment/aegis/crypto/otp/TOTP.java b/app/src/main/java/com/beemdevelopment/aegis/crypto/otp/TOTP.java index 310e1c04..19ae52a1 100644 --- a/app/src/main/java/com/beemdevelopment/aegis/crypto/otp/TOTP.java +++ b/app/src/main/java/com/beemdevelopment/aegis/crypto/otp/TOTP.java @@ -8,13 +8,13 @@ public class TOTP { private TOTP() { } - public static String generateOTP(byte[] secret, String algo, int digits, long period, long seconds) + public static OTP generateOTP(byte[] secret, String algo, int digits, long period, long seconds) throws InvalidKeyException, NoSuchAlgorithmException { long counter = (long) Math.floor((double) seconds / period); return HOTP.generateOTP(secret, algo, digits, counter); } - public static String generateOTP(byte[] secret, String algo, int digits, long period) + public static OTP generateOTP(byte[] secret, String algo, int digits, long period) throws InvalidKeyException, NoSuchAlgorithmException { return generateOTP(secret, algo, digits, period, System.currentTimeMillis() / 1000); } diff --git a/app/src/main/java/com/beemdevelopment/aegis/importers/DatabaseAppImporter.java b/app/src/main/java/com/beemdevelopment/aegis/importers/DatabaseAppImporter.java index 008d0057..9dc02c21 100644 --- a/app/src/main/java/com/beemdevelopment/aegis/importers/DatabaseAppImporter.java +++ b/app/src/main/java/com/beemdevelopment/aegis/importers/DatabaseAppImporter.java @@ -16,6 +16,7 @@ public abstract class DatabaseAppImporter implements DatabaseImporter { // note: keep this list sorted alphabetically LinkedHashMap> importers = new LinkedHashMap<>(); importers.put("Google Authenticator", GoogleAuthAppImporter.class); + importers.put("Steam", SteamAppImporter.class); _importers = Collections.unmodifiableMap(importers); } diff --git a/app/src/main/java/com/beemdevelopment/aegis/importers/SteamAppImporter.java b/app/src/main/java/com/beemdevelopment/aegis/importers/SteamAppImporter.java new file mode 100644 index 00000000..8e0716e5 --- /dev/null +++ b/app/src/main/java/com/beemdevelopment/aegis/importers/SteamAppImporter.java @@ -0,0 +1,80 @@ +package com.beemdevelopment.aegis.importers; + +import android.annotation.SuppressLint; +import android.content.Context; + +import com.beemdevelopment.aegis.db.DatabaseEntry; +import com.beemdevelopment.aegis.encoding.Base64; +import com.beemdevelopment.aegis.encoding.Base64Exception; +import com.beemdevelopment.aegis.otp.OtpInfoException; +import com.beemdevelopment.aegis.otp.SteamInfo; +import com.beemdevelopment.aegis.util.ByteInputStream; +import com.topjohnwu.superuser.io.SuFile; +import com.topjohnwu.superuser.io.SuFileInputStream; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; + +public class SteamAppImporter extends DatabaseAppImporter { + @SuppressLint("SdCardPath") + private static final String _path = "/data/data/com.valvesoftware.android.steam.community/files"; + + private List _objs = new ArrayList<>(); + + public SteamAppImporter(Context context) { + super(context); + } + + @Override + public void parse() throws DatabaseImporterException { + SuFile dir = new SuFile(_path); + for (SuFile file : dir.listFiles((d, name) -> name.startsWith("Steamguard-"))) { + try (SuFileInputStream in = new SuFileInputStream(file)) { + try (ByteInputStream stream = ByteInputStream.create(in)) { + JSONObject obj = new JSONObject(new String(stream.getBytes(), StandardCharsets.UTF_8)); + _objs.add(obj); + } + } catch (IOException | JSONException e) { + throw new DatabaseImporterException(e); + } + } + } + + @Override + public DatabaseImporterResult convert() { + DatabaseImporterResult result = new DatabaseImporterResult(); + + for (JSONObject obj : _objs) { + try { + DatabaseEntry entry = convertEntry(obj); + result.addEntry(entry); + } catch (DatabaseImporterEntryException e) { + result.addError(e); + } + } + + return result; + } + + public DatabaseEntry convertEntry(JSONObject obj) throws DatabaseImporterEntryException{ + try { + byte[] secret = Base64.decode(obj.getString("shared_secret")); + SteamInfo info = new SteamInfo(secret); + + String account = obj.getString("account_name"); + return new DatabaseEntry(info, account, "Steam"); + } catch (JSONException | Base64Exception | OtpInfoException e) { + throw new DatabaseImporterEntryException(e, obj.toString()); + } + } + + @Override + public boolean isEncrypted() { + return false; + } +} diff --git a/app/src/main/java/com/beemdevelopment/aegis/otp/HotpInfo.java b/app/src/main/java/com/beemdevelopment/aegis/otp/HotpInfo.java index fb4d930a..b294951e 100644 --- a/app/src/main/java/com/beemdevelopment/aegis/otp/HotpInfo.java +++ b/app/src/main/java/com/beemdevelopment/aegis/otp/HotpInfo.java @@ -1,6 +1,7 @@ package com.beemdevelopment.aegis.otp; import com.beemdevelopment.aegis.crypto.otp.HOTP; +import com.beemdevelopment.aegis.crypto.otp.OTP; import org.json.JSONException; import org.json.JSONObject; @@ -9,6 +10,8 @@ import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; public class HotpInfo extends OtpInfo { + public static final String ID = "hotp"; + private long _counter; public HotpInfo(byte[] secret, long counter) throws OtpInfoException { @@ -28,7 +31,8 @@ public class HotpInfo extends OtpInfo { @Override public String getOtp() { try { - return HOTP.generateOTP(getSecret(), getAlgorithm(true), getDigits(), getCounter()); + OTP otp = HOTP.generateOTP(getSecret(), getAlgorithm(true), getDigits(), getCounter()); + return otp.toString(); } catch (NoSuchAlgorithmException | InvalidKeyException e) { throw new RuntimeException(); } @@ -36,7 +40,7 @@ public class HotpInfo extends OtpInfo { @Override public String getType() { - return "hotp"; + return ID; } @Override diff --git a/app/src/main/java/com/beemdevelopment/aegis/otp/OtpInfo.java b/app/src/main/java/com/beemdevelopment/aegis/otp/OtpInfo.java index d36eb727..498e2681 100644 --- a/app/src/main/java/com/beemdevelopment/aegis/otp/OtpInfo.java +++ b/app/src/main/java/com/beemdevelopment/aegis/otp/OtpInfo.java @@ -98,13 +98,14 @@ public abstract class OtpInfo implements Serializable { int digits = obj.getInt("digits"); switch (type) { - case "totp": - int period = obj.getInt("period"); - info = new TotpInfo(secret, algo, digits, period); + case TotpInfo.ID: + info = new TotpInfo(secret, algo, digits, obj.getInt("period")); break; - case "hotp": - long counter = obj.getLong("counter"); - info = new HotpInfo(secret, algo, digits, counter); + case SteamInfo.ID: + info = new SteamInfo(secret, algo, digits, obj.getInt("period")); + break; + case HotpInfo.ID: + info = new HotpInfo(secret, algo, digits, obj.getLong("counter")); break; default: throw new OtpInfoException("unsupported otp type: " + type); @@ -126,7 +127,8 @@ public abstract class OtpInfo implements Serializable { } OtpInfo info = (OtpInfo) o; - return Arrays.equals(getSecret(), info.getSecret()) + return getType().equals(info.getType()) + && Arrays.equals(getSecret(), info.getSecret()) && getAlgorithm(false).equals(info.getAlgorithm(false)) && getDigits() == info.getDigits(); } diff --git a/app/src/main/java/com/beemdevelopment/aegis/otp/SteamInfo.java b/app/src/main/java/com/beemdevelopment/aegis/otp/SteamInfo.java new file mode 100644 index 00000000..53ddc600 --- /dev/null +++ b/app/src/main/java/com/beemdevelopment/aegis/otp/SteamInfo.java @@ -0,0 +1,34 @@ +package com.beemdevelopment.aegis.otp; + +import com.beemdevelopment.aegis.crypto.otp.OTP; +import com.beemdevelopment.aegis.crypto.otp.TOTP; + +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; + +public class SteamInfo extends TotpInfo { + public static final String ID = "steam"; + + public SteamInfo(byte[] secret) throws OtpInfoException { + super(secret, "SHA1", 5, 30); + } + + public SteamInfo(byte[] secret, String algorithm, int digits, int period) throws OtpInfoException { + super(secret, algorithm, digits, period); + } + + @Override + public String getOtp() { + try { + OTP otp = TOTP.generateOTP(getSecret(), getAlgorithm(true), getDigits(), getPeriod()); + return otp.toSteamString(); + } catch (InvalidKeyException | NoSuchAlgorithmException e) { + throw new RuntimeException(e); + } + } + + @Override + public String getType() { + return ID; + } +} diff --git a/app/src/main/java/com/beemdevelopment/aegis/otp/TotpInfo.java b/app/src/main/java/com/beemdevelopment/aegis/otp/TotpInfo.java index d366817e..27200592 100644 --- a/app/src/main/java/com/beemdevelopment/aegis/otp/TotpInfo.java +++ b/app/src/main/java/com/beemdevelopment/aegis/otp/TotpInfo.java @@ -1,5 +1,6 @@ package com.beemdevelopment.aegis.otp; +import com.beemdevelopment.aegis.crypto.otp.OTP; import com.beemdevelopment.aegis.crypto.otp.TOTP; import org.json.JSONException; @@ -9,6 +10,8 @@ import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; public class TotpInfo extends OtpInfo { + public static final String ID = "totp"; + private int _period; public TotpInfo(byte[] secret) throws OtpInfoException { @@ -24,7 +27,8 @@ public class TotpInfo extends OtpInfo { @Override public String getOtp() { try { - return TOTP.generateOTP(getSecret(), getAlgorithm(true), getDigits(), getPeriod()); + OTP otp = TOTP.generateOTP(getSecret(), getAlgorithm(true), getDigits(), getPeriod()); + return otp.toString(); } catch (InvalidKeyException | NoSuchAlgorithmException e) { throw new RuntimeException(e); } @@ -32,7 +36,7 @@ public class TotpInfo extends OtpInfo { @Override public String getType() { - return "totp"; + return ID; } @Override diff --git a/app/src/main/java/com/beemdevelopment/aegis/ui/EditEntryActivity.java b/app/src/main/java/com/beemdevelopment/aegis/ui/EditEntryActivity.java index d0c33256..4966196a 100644 --- a/app/src/main/java/com/beemdevelopment/aegis/ui/EditEntryActivity.java +++ b/app/src/main/java/com/beemdevelopment/aegis/ui/EditEntryActivity.java @@ -30,7 +30,6 @@ import android.widget.TableRow; import com.amulyakhare.textdrawable.TextDrawable; import com.avito.android.krop.KropView; -import com.beemdevelopment.aegis.Theme; import com.beemdevelopment.aegis.encoding.Base32; import com.beemdevelopment.aegis.encoding.Base32Exception; import com.beemdevelopment.aegis.helpers.EditTextHelper; @@ -39,6 +38,7 @@ import com.beemdevelopment.aegis.helpers.TextDrawableHelper; import com.beemdevelopment.aegis.otp.HotpInfo; import com.beemdevelopment.aegis.otp.OtpInfo; import com.beemdevelopment.aegis.otp.OtpInfoException; +import com.beemdevelopment.aegis.otp.SteamInfo; import com.beemdevelopment.aegis.otp.TotpInfo; import java.io.ByteArrayInputStream; @@ -167,7 +167,7 @@ public class EditEntryActivity extends AegisActivity { } String type = _origEntry.getInfo().getType(); - _spinnerType.setSelection(getStringResourceIndex(R.array.otp_types_array, type.toUpperCase()), false); + _spinnerType.setSelection(getStringResourceIndex(R.array.otp_types_array, type), false); String algo = _origEntry.getInfo().getAlgorithm(false); _spinnerAlgo.setSelection(getStringResourceIndex(R.array.otp_algo_array, algo), false); @@ -190,11 +190,12 @@ public class EditEntryActivity extends AegisActivity { String type = _spinnerType.getSelectedItem().toString(); switch (type.toLowerCase()) { - case "totp": + case TotpInfo.ID: + case SteamInfo.ID: _rowCounter.setVisibility(View.GONE); _rowPeriod.setVisibility(View.VISIBLE); break; - case "hotp": + case HotpInfo.ID: _rowPeriod.setVisibility(View.GONE); _rowCounter.setVisibility(View.VISIBLE); break; @@ -418,6 +419,14 @@ public class EditEntryActivity extends AegisActivity { super.onActivityResult(requestCode, resultCode, data); } + private int parsePeriod() throws ParseException { + try { + return Integer.parseInt(_textPeriod.getText().toString()); + } catch (NumberFormatException e) { + throw new ParseException("Period is not an integer."); + } + } + private DatabaseEntry parseEntry() throws ParseException { if (_textSecret.length() == 0) { throw new ParseException("Secret is a required field."); @@ -444,16 +453,13 @@ public class EditEntryActivity extends AegisActivity { OtpInfo info; try { switch (type.toLowerCase()) { - case "totp": - int period; - try { - period = Integer.parseInt(_textPeriod.getText().toString()); - } catch (NumberFormatException e) { - throw new ParseException("Period is not an integer."); - } - info = new TotpInfo(secret, algo, digits, period); + case TotpInfo.ID: + info = new TotpInfo(secret, algo, digits, parsePeriod()); break; - case "hotp": + case SteamInfo.ID: + info = new SteamInfo(secret, algo, digits, parsePeriod()); + break; + case HotpInfo.ID: long counter; try { counter = Long.parseLong(_textCounter.getText().toString()); @@ -547,7 +553,7 @@ public class EditEntryActivity extends AegisActivity { private int getStringResourceIndex(@ArrayRes int id, String string) { String[] res = getResources().getStringArray(id); for (int i = 0; i < res.length; i++) { - if (res[i].equals(string)) { + if (res[i].equalsIgnoreCase(string)) { return i; } } diff --git a/app/src/main/java/com/beemdevelopment/aegis/ui/MainActivity.java b/app/src/main/java/com/beemdevelopment/aegis/ui/MainActivity.java index 491a55d7..b39c3066 100644 --- a/app/src/main/java/com/beemdevelopment/aegis/ui/MainActivity.java +++ b/app/src/main/java/com/beemdevelopment/aegis/ui/MainActivity.java @@ -590,8 +590,7 @@ public class MainActivity extends AegisActivity implements EntryListView.Listene super.onAnimationEnd(animation); } }).start(); - } - else if (dy < 0 && _fabMenu.getVisibility() != View.VISIBLE && !isAnimating) { + } else if (dy < 0 && _fabMenu.getVisibility() != View.VISIBLE && !isAnimating) { _fabMenu.setVisibility(View.VISIBLE); _fabMenu.animate() .translationY(0) diff --git a/app/src/main/java/com/beemdevelopment/aegis/ui/PreferencesFragment.java b/app/src/main/java/com/beemdevelopment/aegis/ui/PreferencesFragment.java index 41a403ee..a427e316 100644 --- a/app/src/main/java/com/beemdevelopment/aegis/ui/PreferencesFragment.java +++ b/app/src/main/java/com/beemdevelopment/aegis/ui/PreferencesFragment.java @@ -515,11 +515,6 @@ public class PreferencesFragment extends PreferenceFragmentCompat { _result.putExtra("needsRecreate", true); Snackbar bar = Snackbar.make(getView(), String.format(Locale.getDefault(), getString(R.string.imported_entries_count), entries.size(), errors.size()), Snackbar.LENGTH_LONG); - if (errors.size() == 0) { - bar.setAction(R.string.details, v -> { - - }); - } bar.show(); } diff --git a/app/src/main/java/com/beemdevelopment/aegis/ui/views/EntryHolder.java b/app/src/main/java/com/beemdevelopment/aegis/ui/views/EntryHolder.java index 393ab400..b9a0c9d1 100644 --- a/app/src/main/java/com/beemdevelopment/aegis/ui/views/EntryHolder.java +++ b/app/src/main/java/com/beemdevelopment/aegis/ui/views/EntryHolder.java @@ -13,6 +13,8 @@ import com.amulyakhare.textdrawable.TextDrawable; import com.beemdevelopment.aegis.helpers.TextDrawableHelper; import com.beemdevelopment.aegis.helpers.UiRefresher; import com.beemdevelopment.aegis.otp.HotpInfo; +import com.beemdevelopment.aegis.otp.OtpInfo; +import com.beemdevelopment.aegis.otp.SteamInfo; import com.beemdevelopment.aegis.otp.TotpInfo; import com.beemdevelopment.aegis.R; @@ -139,10 +141,18 @@ public class EntryHolder extends RecyclerView.ViewHolder { } private void updateCode() { - String otp = _entry.getInfo().getOtp(); - String text = otp.substring(0, (otp.length() / 2) - + (otp.length() % 2)) + " " - + otp.substring(otp.length() / 2); + OtpInfo info = _entry.getInfo(); + + String text; + if (info instanceof SteamInfo) { + text = info.getOtp(); + } else { + String otp = info.getOtp(); + text = otp.substring(0, (otp.length() / 2) + + (otp.length() % 2)) + " " + + otp.substring(otp.length() / 2); + } + _profileCode.setText(text); } diff --git a/app/src/main/java/com/beemdevelopment/aegis/ui/views/EntryListView.java b/app/src/main/java/com/beemdevelopment/aegis/ui/views/EntryListView.java index 40b0ba61..20a72d7f 100644 --- a/app/src/main/java/com/beemdevelopment/aegis/ui/views/EntryListView.java +++ b/app/src/main/java/com/beemdevelopment/aegis/ui/views/EntryListView.java @@ -3,7 +3,6 @@ package com.beemdevelopment.aegis.ui.views; import android.content.Context; import android.os.Bundle; -import androidx.annotation.NonNull; import androidx.fragment.app.Fragment; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; @@ -36,8 +35,6 @@ public class EntryListView extends Fragment implements EntryAdapter.Listener { private UiRefresher _refresher; - private RecyclerView.OnScrollChangeListener _onScrollListener; - @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 90e745e7..3cd6f188 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -114,7 +114,7 @@ Ошибка: файл не найден Произошла ошибка при попытке прочитать файл Ошибка: невозможно получить root-доступ - Импортироаано %d записей + Импортироаано %d записей. %d ошибки. Произошла ошибка при попытке экспорта базы данных База данных была экспортирована в: Это действие экспортирует базу данных из личного хранилища Aegis. diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 5174b108..15c88922 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -66,6 +66,7 @@ TOTP HOTP + Steam diff --git a/app/src/test/java/com/beemdevelopment/aegis/HOTPTest.java b/app/src/test/java/com/beemdevelopment/aegis/HOTPTest.java index 345e87a1..e118259e 100644 --- a/app/src/test/java/com/beemdevelopment/aegis/HOTPTest.java +++ b/app/src/test/java/com/beemdevelopment/aegis/HOTPTest.java @@ -6,6 +6,7 @@ import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import com.beemdevelopment.aegis.crypto.otp.HOTP; +import com.beemdevelopment.aegis.crypto.otp.OTP; import static org.junit.Assert.*; @@ -27,8 +28,8 @@ public class HOTPTest { @Test public void vectorsMatch() throws InvalidKeyException, NoSuchAlgorithmException { for (int i = 0; i < _vectors.length; i++) { - String otp = HOTP.generateOTP(_secret, "HmacSHA1", 6, i); - assertEquals(_vectors[i], otp); + OTP otp = HOTP.generateOTP(_secret, "HmacSHA1", 6, i); + assertEquals(_vectors[i], otp.toString()); } } } diff --git a/app/src/test/java/com/beemdevelopment/aegis/TOTPTest.java b/app/src/test/java/com/beemdevelopment/aegis/TOTPTest.java index 3bbfa6c9..1e7aed98 100644 --- a/app/src/test/java/com/beemdevelopment/aegis/TOTPTest.java +++ b/app/src/test/java/com/beemdevelopment/aegis/TOTPTest.java @@ -2,6 +2,7 @@ package com.beemdevelopment.aegis; import org.junit.Test; +import com.beemdevelopment.aegis.crypto.otp.OTP; import com.beemdevelopment.aegis.crypto.otp.TOTP; import com.beemdevelopment.aegis.encoding.Hex; import com.beemdevelopment.aegis.encoding.HexException; @@ -87,8 +88,8 @@ public class TOTPTest { return; } - String otp = TOTP.generateOTP(seed, vector.Algo, 8, 30, vector.Time); - assertEquals(vector.OTP, otp); + OTP otp = TOTP.generateOTP(seed, vector.Algo, 8, 30, vector.Time); + assertEquals(vector.OTP, otp.toString()); } } }