forked from beemdevelopment/Aegis
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMOTP.java
54 lines (41 loc) · 1.57 KB
/
MOTP.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
package com.beemdevelopment.aegis.crypto.otp;
import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
import com.beemdevelopment.aegis.encoding.Hex;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class MOTP {
private final String _code;
private final int _digits;
private MOTP(String code, int digits) {
_code = code;
_digits = digits;
}
@NonNull
public static MOTP generateOTP(byte[] secret, String algo, int digits, int period, String pin)
throws NoSuchAlgorithmException {
return generateOTP(secret, algo, digits, period, pin, System.currentTimeMillis() / 1000);
}
@NonNull
public static MOTP generateOTP(byte[] secret, String algo, int digits, int period, String pin, long time)
throws NoSuchAlgorithmException {
long timeBasedCounter = time / period;
String secretAsString = Hex.encode(secret);
String toDigest = timeBasedCounter + secretAsString + pin;
String code = getDigest(algo, toDigest.getBytes(StandardCharsets.UTF_8));
return new MOTP(code, digits);
}
@VisibleForTesting
@NonNull
protected static String getDigest(String algo, byte[] toDigest) throws NoSuchAlgorithmException {
MessageDigest md = MessageDigest.getInstance(algo);
byte[] digest = md.digest(toDigest);
return Hex.encode(digest);
}
@NonNull
@Override
public String toString() {
return _code.substring(0, _digits);
}
}