Closes #20469
This commit is contained in:
parent
09e30b3c99
commit
637fa741b0
13 changed files with 13 additions and 20 deletions
|
@ -53,8 +53,8 @@ The default algorithm is SHA1. The other, more secure options are SHA256 and SHA
|
||||||
|
|
||||||
The length of the OTP. Short OTPs are user-friendly, easier to type, and easier to remember. Longer OTPs are more secure than shorter OTPs.
|
The length of the OTP. Short OTPs are user-friendly, easier to type, and easier to remember. Longer OTPs are more secure than shorter OTPs.
|
||||||
|
|
||||||
===== Look ahead window
|
===== Look around window
|
||||||
The number of intervals the server attempts to match the hash. This option is present in {project_name} if the clock of the TOTP generator or authentication server become out-of-sync. The default value of 1 is adequate. This option is present in {project_name} to cover when the user's counter gets ahead of the server.
|
The number of previous and following intervals the server attempts to match the hash. This option is present in {project_name} if the clock of the TOTP generator or authentication server become out-of-sync. The default value of 1 is adequate. This option is present in {project_name} to cover when the user's counter gets ahead of the server.
|
||||||
|
|
||||||
===== Initial counter
|
===== Initial counter
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
"webAuthnPolicyRpEntityName": "Human-readable server name as WebAuthn Relying Party",
|
"webAuthnPolicyRpEntityName": "Human-readable server name as WebAuthn Relying Party",
|
||||||
"otpHashAlgorithm": "What hashing algorithm should be used to generate the OTP.",
|
"otpHashAlgorithm": "What hashing algorithm should be used to generate the OTP.",
|
||||||
"otpPolicyDigits": "How many digits should the OTP have?",
|
"otpPolicyDigits": "How many digits should the OTP have?",
|
||||||
"lookAhead": "How far ahead should the server look just in case the token generator and server are out of time sync or counter sync?",
|
"lookAround": "How far around should the server look just in case the token generator and server are out of time sync or counter sync?",
|
||||||
"otpPolicyPeriod": "How many seconds should an OTP token be valid? Defaults to 30 seconds.",
|
"otpPolicyPeriod": "How many seconds should an OTP token be valid? Defaults to 30 seconds.",
|
||||||
"otpPolicyCodeReusable": "Possibility to use the same OTP code again after successful authentication.",
|
"otpPolicyCodeReusable": "Possibility to use the same OTP code again after successful authentication.",
|
||||||
"supportedApplications": "Applications that are known to work with the current OTP policy",
|
"supportedApplications": "Applications that are known to work with the current OTP policy",
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
},
|
},
|
||||||
"otpHashAlgorithm": "OTP hash algorithm",
|
"otpHashAlgorithm": "OTP hash algorithm",
|
||||||
"otpPolicyDigits": "Number of digits",
|
"otpPolicyDigits": "Number of digits",
|
||||||
"lookAhead": "Look ahead window",
|
"lookAround": "Look around window",
|
||||||
"otpPolicyPeriod": "OTP Token period",
|
"otpPolicyPeriod": "OTP Token period",
|
||||||
"otpPolicyPeriodErrorHint": "Value needs to be between 1 second and 2 minutes",
|
"otpPolicyPeriodErrorHint": "Value needs to be between 1 second and 2 minutes",
|
||||||
"otpPolicyCodeReusable": "Reusable token",
|
"otpPolicyCodeReusable": "Reusable token",
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
},
|
},
|
||||||
"otpHashAlgorithm": "OTPハッシュ・アルゴリズム",
|
"otpHashAlgorithm": "OTPハッシュ・アルゴリズム",
|
||||||
"otpPolicyDigits": "桁数",
|
"otpPolicyDigits": "桁数",
|
||||||
"lookAhead": "先読みウィンドウ",
|
|
||||||
"otpPolicyPeriod": "OTPトークンの期間",
|
"otpPolicyPeriod": "OTPトークンの期間",
|
||||||
"initialCounter": "初期カウンター",
|
"initialCounter": "初期カウンター",
|
||||||
"webAuthnPolicySignatureAlgorithms": "署名アルゴリズム",
|
"webAuthnPolicySignatureAlgorithms": "署名アルゴリズム",
|
||||||
|
|
|
@ -12,7 +12,6 @@
|
||||||
},
|
},
|
||||||
"otpHashAlgorithm": "OTP maišos algoritmas",
|
"otpHashAlgorithm": "OTP maišos algoritmas",
|
||||||
"otpPolicyDigits": "Skaitmenų skaičius",
|
"otpPolicyDigits": "Skaitmenų skaičius",
|
||||||
"lookAhead": "Neatitikimo langas",
|
|
||||||
"otpPolicyPeriod": "OTP rakto galiojimo intervalas",
|
"otpPolicyPeriod": "OTP rakto galiojimo intervalas",
|
||||||
"initialCounter": "Pradinė skaitliuko reikšmė",
|
"initialCounter": "Pradinė skaitliuko reikšmė",
|
||||||
"attestationPreference": {
|
"attestationPreference": {
|
||||||
|
|
|
@ -12,7 +12,6 @@
|
||||||
},
|
},
|
||||||
"otpHashAlgorithm": "OTP hash-algoritme",
|
"otpHashAlgorithm": "OTP hash-algoritme",
|
||||||
"otpPolicyDigits": "Antall siffer",
|
"otpPolicyDigits": "Antall siffer",
|
||||||
"lookAhead": "Look Ahead Window",
|
|
||||||
"otpPolicyPeriod": "Engangskode token",
|
"otpPolicyPeriod": "Engangskode token",
|
||||||
"initialCounter": "Initiell teller",
|
"initialCounter": "Initiell teller",
|
||||||
"attestationPreference": {
|
"attestationPreference": {
|
||||||
|
|
|
@ -12,7 +12,6 @@
|
||||||
},
|
},
|
||||||
"otpHashAlgorithm": "Algoritmo de hash OTP",
|
"otpHashAlgorithm": "Algoritmo de hash OTP",
|
||||||
"otpPolicyDigits": "Quantidade de dígitos",
|
"otpPolicyDigits": "Quantidade de dígitos",
|
||||||
"lookAhead": "Look Ahead Window",
|
|
||||||
"otpPolicyPeriod": "Período de token OTP ",
|
"otpPolicyPeriod": "Período de token OTP ",
|
||||||
"initialCounter": "Contador inicial",
|
"initialCounter": "Contador inicial",
|
||||||
"attestationPreference": {
|
"attestationPreference": {
|
||||||
|
|
|
@ -12,7 +12,6 @@
|
||||||
},
|
},
|
||||||
"otpHashAlgorithm": "Алгоритм хеша OTP",
|
"otpHashAlgorithm": "Алгоритм хеша OTP",
|
||||||
"otpPolicyDigits": "Количество цифр",
|
"otpPolicyDigits": "Количество цифр",
|
||||||
"lookAhead": "Окно вперед",
|
|
||||||
"otpPolicyPeriod": "Период токена OTP",
|
"otpPolicyPeriod": "Период токена OTP",
|
||||||
"initialCounter": "Начальное значение счетчика",
|
"initialCounter": "Начальное значение счетчика",
|
||||||
"attestationPreference": {
|
"attestationPreference": {
|
||||||
|
|
|
@ -12,7 +12,6 @@
|
||||||
"webAuthnPolicyRpEntityName": "便于阅读的 WebAuthn依赖方的服务器名称",
|
"webAuthnPolicyRpEntityName": "便于阅读的 WebAuthn依赖方的服务器名称",
|
||||||
"otpHashAlgorithm": "应该使用什么哈希算法来生成 OTP。",
|
"otpHashAlgorithm": "应该使用什么哈希算法来生成 OTP。",
|
||||||
"otpPolicyDigits": "OTP 应该有多少位数?",
|
"otpPolicyDigits": "OTP 应该有多少位数?",
|
||||||
"lookAhead": "如果令牌生成器和服务器不同步或计数器不同步,服务器应该向前查看多久?",
|
|
||||||
"otpPolicyPeriod": "OTP 令牌应该多少秒有效?默认为 30 秒。",
|
"otpPolicyPeriod": "OTP 令牌应该多少秒有效?默认为 30 秒。",
|
||||||
"otpPolicyCodeReusable": "验证成功后可以再次使用相同的 OTP 代码。",
|
"otpPolicyCodeReusable": "验证成功后可以再次使用相同的 OTP 代码。",
|
||||||
"supportedApplications": "已知适用于当前 OTP 策略的应用程序",
|
"supportedApplications": "已知适用于当前 OTP 策略的应用程序",
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
},
|
},
|
||||||
"otpHashAlgorithm": "OTP哈希算法",
|
"otpHashAlgorithm": "OTP哈希算法",
|
||||||
"otpPolicyDigits": "位数",
|
"otpPolicyDigits": "位数",
|
||||||
"lookAhead": "前瞻窗口",
|
|
||||||
"otpPolicyPeriod": "OTP 令牌周期",
|
"otpPolicyPeriod": "OTP 令牌周期",
|
||||||
"otpPolicyPeriodErrorHint": "时间需要在 1 秒到 2 分钟之间",
|
"otpPolicyPeriodErrorHint": "时间需要在 1 秒到 2 分钟之间",
|
||||||
"otpPolicyCodeReusable": "可重复使用的令牌",
|
"otpPolicyCodeReusable": "可重复使用的令牌",
|
||||||
|
|
|
@ -204,14 +204,14 @@ export const OtpPolicy = ({ realm, realmUpdated }: OtpPolicyProps) => {
|
||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
<FormGroup
|
<FormGroup
|
||||||
label={t("lookAhead")}
|
label={t("lookAround")}
|
||||||
labelIcon={
|
labelIcon={
|
||||||
<HelpItem
|
<HelpItem
|
||||||
helpText={t("authentication-help:lookAhead")}
|
helpText={t("authentication-help:lookAround")}
|
||||||
fieldLabelId="authentication:lookAhead"
|
fieldLabelId="authentication:lookAround"
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
fieldId="lookAhead"
|
fieldId="lookAround"
|
||||||
>
|
>
|
||||||
<Controller
|
<Controller
|
||||||
name="otpPolicyLookAheadWindow"
|
name="otpPolicyLookAheadWindow"
|
||||||
|
@ -225,7 +225,7 @@ export const OtpPolicy = ({ realm, realmUpdated }: OtpPolicyProps) => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<NumberInput
|
<NumberInput
|
||||||
id="lookAhead"
|
id="lookAround"
|
||||||
value={value}
|
value={value}
|
||||||
min={MIN_VALUE}
|
min={MIN_VALUE}
|
||||||
onPlus={() => setValue(value + 1)}
|
onPlus={() => setValue(value + 1)}
|
||||||
|
|
|
@ -81,7 +81,7 @@ public class TimeBasedOTP extends HmacOTP {
|
||||||
public boolean validateTOTP(String token, byte[] secret) {
|
public boolean validateTOTP(String token, byte[] secret) {
|
||||||
long currentInterval = this.clock.getCurrentInterval();
|
long currentInterval = this.clock.getCurrentInterval();
|
||||||
|
|
||||||
for (int i = 0; i <= (lookAheadWindow * 2); i++) {
|
for (int i = 0; i <= (lookAroundWindow * 2); i++) {
|
||||||
long delta = clockSkewIndexToDelta(i);
|
long delta = clockSkewIndexToDelta(i);
|
||||||
long adjustedInterval = currentInterval + delta;
|
long adjustedInterval = currentInterval + delta;
|
||||||
|
|
||||||
|
|
|
@ -36,12 +36,12 @@ public class HmacOTP {
|
||||||
private static final int[] DIGITS_POWER = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000};
|
private static final int[] DIGITS_POWER = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000};
|
||||||
protected final String algorithm;
|
protected final String algorithm;
|
||||||
protected final int numberDigits;
|
protected final int numberDigits;
|
||||||
protected final int lookAheadWindow;
|
protected final int lookAroundWindow;
|
||||||
|
|
||||||
public HmacOTP(int numberDigits, String algorithm, int delayWindow) {
|
public HmacOTP(int numberDigits, String algorithm, int delayWindow) {
|
||||||
this.numberDigits = numberDigits;
|
this.numberDigits = numberDigits;
|
||||||
this.algorithm = algorithm;
|
this.algorithm = algorithm;
|
||||||
this.lookAheadWindow = delayWindow;
|
this.lookAroundWindow = delayWindow;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String generateSecret(int length) {
|
public static String generateSecret(int length) {
|
||||||
|
@ -80,7 +80,7 @@ public class HmacOTP {
|
||||||
public int validateHOTP(String token, byte[] key, int counter) {
|
public int validateHOTP(String token, byte[] key, int counter) {
|
||||||
|
|
||||||
int newCounter = counter;
|
int newCounter = counter;
|
||||||
for (newCounter = counter; newCounter <= counter + lookAheadWindow; newCounter++) {
|
for (newCounter = counter; newCounter <= counter + lookAroundWindow; newCounter++) {
|
||||||
String candidate = generateHOTP(key, newCounter);
|
String candidate = generateHOTP(key, newCounter);
|
||||||
if (candidate.equals(token)) {
|
if (candidate.equals(token)) {
|
||||||
return newCounter + 1;
|
return newCounter + 1;
|
||||||
|
|
Loading…
Reference in a new issue