Это алгоритм шифрования, основанный на времени. Он используется в ситуациях, где требования к безопасности особенно высоки, например, в играх или банковских сервисах, для дополнительной аутентификации.
Класс инструментов шифрования в основном основан на google-authenticator.
Принцип шифрования: используется алгоритм HMAC с использованием хеш-функции, которая принимает в качестве входных данных ключ и сообщение и генерирует выходное сообщение — дайджест сообщения.
Параметры ключа: генерируется с помощью base32. Параметры сообщения: временная метка (в секундах) / временной интервал (TimeStep). (Подсказка: например, если TimeStep = 30, то пароли будут одинаковыми в течение 30 секунд, это погрешность в 30 с.)
/*PasscodeGenerator.java*/
private String generateResponseCode() {
try {
byte[] KEYBYTES = Base32String.decode(AUTH_KEY);
Mac mac = Mac.getInstance("HMACSHA1");
mac.init(new SecretKeySpec(KEYBYTES, ""));
//Выполнение шифрования doFinal, передаётся источник шифрования, тип - byte[], поэтому нам нужно преобразовать значение текущего временного интервала в byte[]
long time = TimeUtils.getValueAtTime();
byte[] data = long2bytes(time);
//После шифрования тип - byte[], так как нам нужен цифровой пароль, этот алгоритм использует преобразование byte[] в int
byte[] hash = mac.doFinal(data);
//Этот результат преобразуется в int, но не соответствует нашему требованию к n-значному паролю, здесь используется метод взятия n-значного остатка (например, вычисленный результат: 123456789, предположим, что нам нужен 8-значный пароль, тогда 123456789%10000000 =23456789)
int truncatedHash = bytes2int(hash);
//Для truncatedHash выполняется операция взятия остатка, чтобы получить число, которое может быть меньше n-значного. Поэтому мы обрабатываем недостающие цифры, заполняя нулями
int pinValue = truncatedHash % Double.valueOf(Math.pow(10, PASS_CODE_LENGTH)).intValue();
return padOutput(pinValue);
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
/**
* Получение значения текущего времени в интервале
*
* @param time
* @return
*/
public static long getValueAtTime(long time) {
long timeSinceStartTime = time - mStartTime;
if (timeSinceStartTime >= 0) {
return timeSinceStartTime / mTimeStep;
} else {
return (timeSinceStartTime - (mTimeStep - 1)) / mTimeStep;
}
}
/**
* PasscodeGenerator.java
* long to byte[] алгоритм
*/
private byte[] long2bytes(long state)
throws GeneralSecurityException {
byte[] value = ByteBuffer.allocate(8).putLong(state).array();
return value;
}
/**
* PasscodeGenerator.java
* byte[] to int алгоритм
*/
private int bytes2int(byte[] hash){
int offset = hash[hash.length - 1] & 0xF;
int truncatedHash = hashToInt(hash, offset) & 0x7FFFFFFF;
return truncatedHash;
}
//Обработка недостающих цифр с заполнением нулями
private String padOutput(int value) {
String result = Integer.toString(value);
//В соответствии с результатом добавляем нули
for (int i = result.length(); i < PASS_CODE_LENGTH; i++) {
result = "0" + result;
}
return result;
}
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Комментарии ( 0 )