OTP-Java-Redme

OTP-Java

Build & Test
Codacy Badge

用于Java实现的小型且易于使用的一次性密码生成器 RFC 4226 (HOTP) 和RFC 6238 (TOTP).

目录

特点

支持以下功能:

  1. 生成秘钥
  2. 基于时间的一次性密码(TOTP,RFC 6238)生成,基于当前时间、特定时间、OTPAuth URI等不同的HMAC算法。
  3. 基于计数器和OTPAuth URI的基于HMAC的一次性密码(HOTP,RFC 4226)生成。
  4. OTP验证
  5. 生成OTP Auth URI

安装

Maven

1
2
3
4
5
<dependency>
<groupId>com.github.bastiaanjansen</groupId>
<artifactId>otp-java</artifactId>
<version>2.0.2</version>
</dependency>

Gradle

1
implementation 'com.github.bastiaanjansen:otp-java:2.0.2'

Scala SBT

1
libraryDependencies += "com.github.bastiaanjansen" % "otp-java" % "2.0.2"

Apache Ivy

1
<dependency org="com.github.bastiaanjansen" name="otp-java" rev="2.0.2" />

或者您可以从 GitHub releases page.

使用

基于事件的一次性密码 HOTP (Counter-based one-time passwords)

初始化HOTP实例

使用“HOTPGenerator”创建“HOTPGenerator”实例。创建方法如下:

1
2
3
4
// 共享密钥,可以是任意字符串,长度一般为8-10个字符  将共享密钥转换为字节数组
byte[] secret = "VV3KOX7UQJ4KYAKOHMZPPH3US4CJIMH6F3ZKNB5C2OOBQ6V2KIYHM27Q".getBytes();
// 创建“HOTPGenerator”实例
HOTPGenerator hotp = new HOTPGenerator.Builder(secret).build();

上面的构造器创建了一个HOTP实例,其默认值为passwordLength=6,algorithm=SHA1。使用构造器可以更改这些默认值:

1
2
3
4
5
6
HOTPGenerator hotp = new HOTPGenerator.Builder(secret)
// 生成的密码长度
.withPasswordLength(8)
// 加密方式
.withAlgorithm(HMACAlgorithm.SHA256)
.build();

当您还没有秘钥时,可以让库生成它:

1
2
3
4
5
// 生成160位的秘钥
byte[] secret = SecretGenerator.generate();

// 生成具有自定义位数的秘钥
byte[] secret = SecretGenerator.generate(512);

还可以基于OTPAuth URI创建HOTP实例。当未指定算法或数字时,将使用默认值。

1
2
URI uri = new URI("otpauth://hotp/issuer?secret=ABCDEFGHIJKLMNOP&algorithm=SHA1&digits=6&counter=8237");
HOTPGenerator hotp = HOTPGenerator.fromURI(uri);

获取关于构造器的信息:

1
2
3
4
// 6 获取生成的的密码长度
int passwordLength = hotp.getPasswordLength();
// HMACAlgorithm.SHA1 获取加密方式
HMACAlgorithm algorithm = hotp.getAlgorithm();

HOTP代码的生成

创建HOTP类的实例后,可以使用“generate()”方法生成代码:

1
2
3
4
5
6
7
8
9
10
11
12
try {
int counter = 5;
String code = hotp.generate(counter);

// 验证令牌:
boolean isValid = hotp.verify(code, counter);

// 或使用延迟窗口进行验证
boolean isValid = hotp.verify(code, counter, 2);
} catch (IllegalStateException e) {
// 非法状态异常
}

基于时间的一次性密码 TOTP (Time-based one-time passwords)

初始化TOTP实例

TOTP可以接受更多的参数:“passwordLength”、“period”、“algorithm”和“secret”。

默认值为:passwordLength=6,period=30,algorithm=SHA1。

1
2
3
4
5
6
7
8
9
10
11
12
// 生成一个共享秘钥 (或者使用你自己的共享秘钥)
byte[] secret = SecretGenerator.generate();

TOTPGenerator totp = new TOTPGenerator.Builder(secret)
.withHOTPGenerator(builder -> {
builder.withPasswordLength(6);
// 还支持SHA256和SHA512
builder.withAlgorithm(HMACAlgorithm.SHA1);
})
// 密码有效时间(单位秒)
.withPeriod(Duration.ofSeconds(30))
.build();

或者从OTPAuth URI创建一个“TOTP”实例:

1
2
URI uri = new URI("otpauth://totp/issuer?secret=ABCDEFGHIJKLMNOP&algorithm=SHA1&digits=6&period=30");
TOTPGenerator totpGenerator = TOTPGenerator.fromURI(uri);

获取关于构造器的信息:

1
2
3
4
5
6
7
8
// 获取共享秘钥
byte[] secret = totpGenerator.getSecret();
// 6 获取生成的的密码长度
int passwordLength = totpGenerator.getPasswordLength();
// HMACAlgorithm.SHA1 获取加密方式
HMACAlgorithm algorithm = totpGenerator.getAlgorithm();
// Duration.ofSeconds(30) 密码有效时间(单位秒)
Duration period = totpGenerator.getPeriod();

生成TOTP代码

创建TOTP类的实例后,可以使用“now()”方法生成代码,类似于HOTP类:

1
2
3
4
5
6
7
8
try {
String code = totpGenerator.now();

// 验证令牌:
boolean isValid = totpGenerator.verify(code);
} catch (IllegalStateException e) {
// 非法状态异常
}

以上代码将根据当前时间生成一个基于时间的一次性密码。除了当前时间之外,API还支持基于“timeSince1970”(以秒为单位)、“Date”和“Instant”创建代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
try {
// 基于当前时间
totpGenerator.now();

// Based on specific date
totpGenerator.at(new Date());

// 基于具体的日期
totpGenerator.at(LocalDate.of(2023, 3, 2));

// 基于时间戳
totpGenerator.at(9238346823);

// 基于一个实例
totpGenerator.at(Instant.now());
} catch (IllegalStateException e) {
// 非法状态异常
}

OTPAuth URI的生成

要轻松生成OTPAuth URI以便于登录,请对“HOTP”和“TOTP”使用“getURI()”方法。以“TOTP”为例:

1
2
3
4
5
TOTPGenerator totpGenerator = new TOTPGenerator.Builder(secret).build();

URI uri = totpGenerator.getURI("issuer", "account");
// otpauth://totp/issuer:account?period=30&digits=6&secret=SECRET&algorithm=SHA1

恢复代码

通常,服务提供“备份代码”或“恢复代码”,当用户无法再访问2FA设备时可以使用这些代码。通常是因为2FA设备是一部手机,可能会丢失或被盗。

由于恢复代码生成不是OTP规范的一部分,因此不可能使用此库生成恢复代码,应单独实现。

许可

OTP Java在MIT许可证下可用。有关更多信息,请参阅许可证。

Stargazers repo roster for @BastiaanJansen/otp-java

原文链接

https://github.com/BastiaanJansen/otp-java