Hi,
Ich möchte mal den Google Authentificator nachprogrammieren(Dies hat ein bestimmten Grund, den ich aktuell nicht sagen möchte).
Im Internet habe ich gelesen, dass der Google Authentifikator den TOTP Algorythmus verwendet(Quelle: https://en.wikipedia.org/wiki/Google_Authenticator).
Deswegen habe ich mir die Seite https://datatracker.ietf.org/doc/html/rfc6238 durchgelesen und verstanden, bis auf die Sache, wie man auf die Variable seed[Seite 12, erste Variable in der main Methode] kommt. Oder muss ich den HOTP Algorythmus nehmen? Oder ist im Code ein Fehler? Auf jeden Fall bekomme ich z.B. von Discord den 2FA-Schlüssel '6wkz kzou f7i3 ueju'(Der Schlüssel wird von mir nicht verwendet, erspart euch die Mühe), welchen Key muss ich dann übergeben und wie komme ich dahin
Code:
Ich möchte mal den Google Authentificator nachprogrammieren(Dies hat ein bestimmten Grund, den ich aktuell nicht sagen möchte).
Im Internet habe ich gelesen, dass der Google Authentifikator den TOTP Algorythmus verwendet(Quelle: https://en.wikipedia.org/wiki/Google_Authenticator).
Deswegen habe ich mir die Seite https://datatracker.ietf.org/doc/html/rfc6238 durchgelesen und verstanden, bis auf die Sache, wie man auf die Variable seed[Seite 12, erste Variable in der main Methode] kommt. Oder muss ich den HOTP Algorythmus nehmen? Oder ist im Code ein Fehler? Auf jeden Fall bekomme ich z.B. von Discord den 2FA-Schlüssel '6wkz kzou f7i3 ueju'(Der Schlüssel wird von mir nicht verwendet, erspart euch die Mühe), welchen Key muss ich dann übergeben und wie komme ich dahin
Code:
Java:
package test;
import java.lang.reflect.UndeclaredThrowableException;
import java.math.BigInteger;
import java.security.GeneralSecurityException;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
public class Test3 {
private static final int[] DIGITS_POWER
// 0 1 2 3 4 5 6 7 8
= {1,10,100,1000,10000,100000,1000000,10000000,100000000 };
private static byte[] hmac_sha(String crypto, byte[] keyBytes,
byte[] text){
try {
Mac hmac;
hmac = Mac.getInstance(crypto);
SecretKeySpec macKey =
new SecretKeySpec(keyBytes, "RAW");
hmac.init(macKey);
return hmac.doFinal(text);
} catch (GeneralSecurityException gse) {
throw new UndeclaredThrowableException(gse);
}
}
private static byte[] hexStr2Bytes(String hex){
// Adding one byte to get the right conversion
// Values starting with "0" can be converted
byte[] bArray = new BigInteger("10" + hex,16).toByteArray();
// Copy all the REAL bytes, not the "first"
byte[] ret = new byte[bArray.length - 1];
for (int i = 0; i < ret.length; i++)
ret[i] = bArray[i+1];
return ret;
}
public static String generateTOTP(String key,
String time,
String returnDigits,
String crypto){
int codeDigits = Integer.decode(returnDigits).intValue();
String result = null;
// Using the counter
// First 8 bytes are for the movingFactor
// Compliant with base RFC 4226 (HOTP)
while (time.length() < 16 )
time = "0" + time;
// Get the HEX in a Byte[]
byte[] msg = hexStr2Bytes(time);
byte[] k = hexStr2Bytes(key);
byte[] hash = hmac_sha(crypto, k, msg);
// put selected bytes into result int
int offset = hash[hash.length - 1] & 0xf;
int binary =
((hash[offset] & 0x7f) << 24) |
((hash[offset + 1] & 0xff) << 16) |
((hash[offset + 2] & 0xff) << 8) |
(hash[offset + 3] & 0xff);
int otp = binary % DIGITS_POWER[codeDigits];
result = Integer.toString(otp);
while (result.length() < codeDigits) {
result = "0" + result;
}
return result;
}
private static long getAkT() {
return System.currentTimeMillis() / 1000 / 30;
}
public static void main(String[] args) {
System.out.println(generateTOTP("6wkzkzouf7i3ueju", Long.toHexString(getAkT()).toUpperCase(), "6", "HmacSHA1"));
}
}