- Getting the response from the Yubikey through NFC

- Added TOTP class to calculate 6 digits code using RFC6238
This commit is contained in:
Javier Varona 2018-08-20 20:28:46 -04:00
parent c4f0e9ef41
commit 77b5d956ea
4 changed files with 76 additions and 39 deletions

View file

@ -94,8 +94,8 @@ public class IntroActivity extends AppCompatActivity {
//startActivity(intent); //startActivity(intent);
} else { } else {
//Intent intent = new Intent(this, CreateSeedActivity.class); //Intent intent = new Intent(this, CreateSeedActivity.class);
//Intent intent = new Intent(this, BoardActivity.class); Intent intent = new Intent(this, BoardActivity.class);
Intent intent = new Intent(this, PocketRequestActivity.class); //Intent intent = new Intent(this, PocketRequestActivity.class);
startActivity(intent); startActivity(intent);
} }

View file

@ -64,26 +64,6 @@ public class PocketRequestActivity extends AppCompatActivity {
mNfcAdapter = NfcAdapter.getDefaultAdapter(this); mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
this.configureForegroundDispatch(); 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(){ public void configureForegroundDispatch(){
@ -130,17 +110,27 @@ public class PocketRequestActivity extends AppCompatActivity {
tagIsoDep.connect(); tagIsoDep.connect();
YkOathApi ykOathApi = new YkOathApi(tagIsoDep); 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[] timeStep = ByteBuffer.allocate(8).putLong(unixTime / 30L).array();
byte[] response; byte[] response;
response = ykOathApi.calculate("cy.agorise.crystalwallet",timeStep,true); response = ykOathApi.calculate("cy.agorise.crystalwallet",timeStep,true);
response[0]. ByteBuffer responseBB = ByteBuffer.wrap(response);
private fun formatTruncated(data: ByteArray): String { int digits = (int)responseBB.get();
return with(ByteBuffer.wrap(data)) { String challengeString = ""+(responseBB.getInt());
val digits = get().toInt() String challenge = challengeString.substring(challengeString.length()-digits);
int.toString().takeLast(digits).padStart(digits, '0') 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(); tagIsoDep.close();
//ykOathApi. //ykOathApi.

View file

@ -1,5 +1,11 @@
package cy.agorise.crystalwallet.util; 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. * Created by Henry Varona on 29/1/2018.
*/ */
@ -19,4 +25,35 @@ public class PasswordManager {
public static String encriptPassword(String password){ public static String encriptPassword(String password){
return 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);
}
} }

View file

@ -6,6 +6,8 @@ import java.text.DateFormat;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
import javax.crypto.Mac; import javax.crypto.Mac;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec; import javax.crypto.spec.SecretKeySpec;
import java.math.BigInteger; import java.math.BigInteger;
import java.util.TimeZone; import java.util.TimeZone;
@ -30,7 +32,7 @@ public class TOTP {
*/ */
private static byte[] hmac_sha(String crypto, byte[] keyBytes, private static byte[] hmac_sha(String crypto, byte[] keyBytes,
byte[] text){ byte[] text, byte[] salt){
try { try {
Mac hmac; Mac hmac;
hmac = Mac.getInstance(crypto); hmac = Mac.getInstance(crypto);
@ -38,6 +40,10 @@ public class TOTP {
new SecretKeySpec(keyBytes, "RAW"); new SecretKeySpec(keyBytes, "RAW");
hmac.init(macKey); hmac.init(macKey);
return hmac.doFinal(text); 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) { } catch (GeneralSecurityException gse) {
throw new UndeclaredThrowableException(gse); throw new UndeclaredThrowableException(gse);
} }
@ -82,8 +88,9 @@ public class TOTP {
public static String generateTOTP(String key, public static String generateTOTP(String key,
String time, String time,
String returnDigits){ String returnDigits,
return generateTOTP(key, time, returnDigits, "HmacSHA1"); byte[] salt){
return generateTOTP(key, time, returnDigits, "PBKDF2WithHmacSHA1", salt);
} }
@ -101,8 +108,9 @@ public class TOTP {
public static String generateTOTP256(String key, public static String generateTOTP256(String key,
String time, String time,
String returnDigits){ String returnDigits,
return generateTOTP(key, time, returnDigits, "HmacSHA256"); byte[] salt){
return generateTOTP(key, time, returnDigits, "HmacSHA256", salt);
} }
/** /**
@ -119,8 +127,9 @@ public class TOTP {
public static String generateTOTP512(String key, public static String generateTOTP512(String key,
String time, String time,
String returnDigits){ String returnDigits,
return generateTOTP(key, time, returnDigits, "HmacSHA512"); byte[] salt){
return generateTOTP(key, time, returnDigits, "HmacSHA512", salt);
} }
@ -140,7 +149,8 @@ public class TOTP {
public static String generateTOTP(String key, public static String generateTOTP(String key,
String time, String time,
String returnDigits, String returnDigits,
String crypto){ String crypto,
byte[] salt){
int codeDigits = Integer.decode(returnDigits).intValue(); int codeDigits = Integer.decode(returnDigits).intValue();
String result = null; String result = null;
@ -153,7 +163,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[] k = hexStr2Bytes(key);
byte[] hash = hmac_sha(crypto, k, msg); byte[] hash = hmac_sha(crypto, k, msg, salt);
// 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;