From 77b5d956ea6adb2d53bc74e1e574500004c99256 Mon Sep 17 00:00:00 2001 From: Javier Varona Date: Mon, 20 Aug 2018 20:28:46 -0400 Subject: [PATCH] - Getting the response from the Yubikey through NFC - Added TOTP class to calculate 6 digits code using RFC6238 --- .../activities/IntroActivity.java | 4 +- .../activities/PocketRequestActivity.java | 46 ++++++++----------- .../crystalwallet/util/PasswordManager.java | 37 +++++++++++++++ .../crystalwallet/util/yubikey/TOTP.java | 28 +++++++---- 4 files changed, 76 insertions(+), 39 deletions(-) diff --git a/app/src/main/java/cy/agorise/crystalwallet/activities/IntroActivity.java b/app/src/main/java/cy/agorise/crystalwallet/activities/IntroActivity.java index c557bde..9d4eaf1 100644 --- a/app/src/main/java/cy/agorise/crystalwallet/activities/IntroActivity.java +++ b/app/src/main/java/cy/agorise/crystalwallet/activities/IntroActivity.java @@ -94,8 +94,8 @@ public class IntroActivity extends AppCompatActivity { //startActivity(intent); } else { //Intent intent = new Intent(this, CreateSeedActivity.class); - //Intent intent = new Intent(this, BoardActivity.class); - Intent intent = new Intent(this, PocketRequestActivity.class); + Intent intent = new Intent(this, BoardActivity.class); + //Intent intent = new Intent(this, PocketRequestActivity.class); startActivity(intent); } diff --git a/app/src/main/java/cy/agorise/crystalwallet/activities/PocketRequestActivity.java b/app/src/main/java/cy/agorise/crystalwallet/activities/PocketRequestActivity.java index 9eb3919..687f810 100644 --- a/app/src/main/java/cy/agorise/crystalwallet/activities/PocketRequestActivity.java +++ b/app/src/main/java/cy/agorise/crystalwallet/activities/PocketRequestActivity.java @@ -64,26 +64,6 @@ public class PocketRequestActivity extends AppCompatActivity { mNfcAdapter = NfcAdapter.getDefaultAdapter(this); this.configureForegroundDispatch(); - - - String clave = "12345678901234567890"; - - char[] ch = clave.toCharArray(); - - StringBuilder builder = new StringBuilder(); - for (char c : ch) { - String hexCode=String.format("%H", c); - builder.append(hexCode); - } - String claveHex = String.format("%040x", new BigInteger(1, clave.getBytes())); - - - long time = 1111111109/30; - String steps = Long.toHexString(time).toUpperCase(); - while(steps.length() < 16) steps = "0" + steps; - Log.i("TEST", TOTP.generateTOTP( - claveHex, - steps, "6", "HmacSHA1")); } public void configureForegroundDispatch(){ @@ -130,17 +110,27 @@ public class PocketRequestActivity extends AppCompatActivity { tagIsoDep.connect(); YkOathApi ykOathApi = new YkOathApi(tagIsoDep); - /*long unixTime = System.currentTimeMillis() / 1000L; + long unixTime = System.currentTimeMillis() / 1000L; byte[] timeStep = ByteBuffer.allocate(8).putLong(unixTime / 30L).array(); byte[] response; response = ykOathApi.calculate("cy.agorise.crystalwallet",timeStep,true); - response[0]. - private fun formatTruncated(data: ByteArray): String { - return with(ByteBuffer.wrap(data)) { - val digits = get().toInt() - int.toString().takeLast(digits).padStart(digits, '0') - } - }*/ + ByteBuffer responseBB = ByteBuffer.wrap(response); + int digits = (int)responseBB.get(); + String challengeString = ""+(responseBB.getInt()); + String challenge = challengeString.substring(challengeString.length()-digits); + while (challenge.length() < digits){ + challenge = '0'+challenge; + } + + String storedChallenge = PasswordManager.totpd(yubikeySecret, unixTime, ykOathApi.getDeviceSalt()); + + Toast.makeText(this, "Secret:"+yubikeySecret+" StoredChallenge:"+storedChallenge+" Yubikey:"+challenge , Toast.LENGTH_LONG).show(); + + Log.i("TOTP","Secret: "+yubikeySecret); + Log.i("TOTP", "Unixtime: "+unixTime); + Log.i("TOTP", "Step: "+unixTime/30L); + Log.i("TOTP", "StoredChallenge: "+storedChallenge); + Log.i("TOTP", "Yubikey: "+challenge); tagIsoDep.close(); //ykOathApi. diff --git a/app/src/main/java/cy/agorise/crystalwallet/util/PasswordManager.java b/app/src/main/java/cy/agorise/crystalwallet/util/PasswordManager.java index 7f52970..2705ff3 100644 --- a/app/src/main/java/cy/agorise/crystalwallet/util/PasswordManager.java +++ b/app/src/main/java/cy/agorise/crystalwallet/util/PasswordManager.java @@ -1,5 +1,11 @@ package cy.agorise.crystalwallet.util; +import android.util.Log; + +import java.math.BigInteger; + +import cy.agorise.crystalwallet.util.yubikey.TOTP; + /** * Created by Henry Varona on 29/1/2018. */ @@ -19,4 +25,35 @@ public class PasswordManager { public static String encriptPassword(String password){ return password; } + + public static String totpd(String sharedSecret, long unixtime, byte[] salt){ + char[] ch = sharedSecret.toCharArray(); + + StringBuilder builder = new StringBuilder(); + for (char c : ch) { + String hexCode=String.format("%H", c); + builder.append(hexCode); + } + String secretHex = String.format("%040x", new BigInteger(1, sharedSecret.getBytes())); + + long time = unixtime/30L; + + String steps = Long.toHexString(time).toUpperCase(); + + + + /*for (int i=0;i<64;i++){ + steps = Long.toHexString(time+i).toUpperCase(); + Log.i("TOTPTEST", TOTP.generateTOTP( + secretHex, + steps, + "6", "HmacSHA1", salt)); + secretHex = "00"+secretHex; + }*/ + + return TOTP.generateTOTP( + secretHex, + steps, + "6", "HmacSHA1", salt); + } } diff --git a/app/src/main/java/cy/agorise/crystalwallet/util/yubikey/TOTP.java b/app/src/main/java/cy/agorise/crystalwallet/util/yubikey/TOTP.java index 5b92530..368f0cd 100644 --- a/app/src/main/java/cy/agorise/crystalwallet/util/yubikey/TOTP.java +++ b/app/src/main/java/cy/agorise/crystalwallet/util/yubikey/TOTP.java @@ -6,6 +6,8 @@ import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; import javax.crypto.Mac; +import javax.crypto.SecretKeyFactory; +import javax.crypto.spec.PBEKeySpec; import javax.crypto.spec.SecretKeySpec; import java.math.BigInteger; import java.util.TimeZone; @@ -30,7 +32,7 @@ public class TOTP { */ private static byte[] hmac_sha(String crypto, byte[] keyBytes, - byte[] text){ + byte[] text, byte[] salt){ try { Mac hmac; hmac = Mac.getInstance(crypto); @@ -38,6 +40,10 @@ public class TOTP { new SecretKeySpec(keyBytes, "RAW"); hmac.init(macKey); return hmac.doFinal(text); + /*PBEKeySpec spec = new PBEKeySpec((new String(text)).toCharArray(), salt, 1000, 128); + SecretKeyFactory skf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); + byte[] hash = skf.generateSecret(spec).getEncoded(); + return hash;*/ } catch (GeneralSecurityException gse) { throw new UndeclaredThrowableException(gse); } @@ -82,8 +88,9 @@ public class TOTP { public static String generateTOTP(String key, String time, - String returnDigits){ - return generateTOTP(key, time, returnDigits, "HmacSHA1"); + String returnDigits, + byte[] salt){ + return generateTOTP(key, time, returnDigits, "PBKDF2WithHmacSHA1", salt); } @@ -101,8 +108,9 @@ public class TOTP { public static String generateTOTP256(String key, String time, - String returnDigits){ - return generateTOTP(key, time, returnDigits, "HmacSHA256"); + String returnDigits, + byte[] salt){ + return generateTOTP(key, time, returnDigits, "HmacSHA256", salt); } /** @@ -119,8 +127,9 @@ public class TOTP { public static String generateTOTP512(String key, String time, - String returnDigits){ - return generateTOTP(key, time, returnDigits, "HmacSHA512"); + String returnDigits, + byte[] salt){ + return generateTOTP(key, time, returnDigits, "HmacSHA512", salt); } @@ -140,7 +149,8 @@ public class TOTP { public static String generateTOTP(String key, String time, String returnDigits, - String crypto){ + String crypto, + byte[] salt){ int codeDigits = Integer.decode(returnDigits).intValue(); String result = null; @@ -153,7 +163,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, k, msg, salt); // put selected bytes into result int int offset = hash[hash.length - 1] & 0xf;