- Getting the response from the Yubikey through NFC
- Added TOTP class to calculate 6 digits code using RFC6238
This commit is contained in:
parent
c4f0e9ef41
commit
77b5d956ea
4 changed files with 76 additions and 39 deletions
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue