我开发了以下程序来生成OTP(一次性密码),现在请指教是否有其他更好更安全的方法,我可以在OTP的上下文中使用
// Java code to explain how to generate OTP
// Here we are using random() method of util
// class in Java
import java.util.*;
public class NewClass
{
static char[] OTP(int len)
{
System.out.println("Generating OTP using random() : ");
System.out.print("You OTP is : ");
// Using numeric values
String numbers = "0123456789";
// Using random method
Random rndm_method = new Random();
char[] otp = new char[len];
for (int i = 0; i < len; i++)
{
// Use of charAt() method : to get character value
// Use of nextInt() as it is scanning the value as int
otp[i] =
numbers.charAt(rndm_method.nextInt(numbers.length()));
}
return otp;
}
public static void main(String[] args)
{
int length = 4;
System.out.println(OTP(length));
}
}
答案 0 :(得分:1)
正如评论所指出的,一次性密码只是一个随机数字或字符串。
查看代码,您正在使用Random
类。这对于随机序列的质量在很大程度上无关的应用来说很好。但是,SecureRandom
的标准实现产生了一个高度可预测(自相关)的数字序列;见https://stackoverflow.com/a/38345694/139985。您应该使用nextInt(numbers.length())
代替。
我怀疑你使用Random
会放大自相关性......所以如果你继续使用{{1}},Samwell的建议会有所帮助。
答案 1 :(得分:0)
使用 Java 8+,以下代码将生成 4 位 OTP。只需将 random.ints(...) 方法中的 4 替换为您在 OTP 中所需的位数。
编辑: 我读到 SecureRandom 是另一个用于生成随机数的类(提供额外的安全性)。如果您愿意,您可以根据需要使用它,而不是旧的 Random 类。
...
import java.util.Random;
//Or
//import java.security.SecureRandom;
...
Random random = new Random();
//Or
//SecureRandom random = new SecureRandom();
random.ints(4, 0, 10).mapToObj(Integer::toString).reduce((a, b) -> a + b)
.ifPresent(System.out::println);
如果你想把值变成一个字符串而不是仅仅打印它,那么:
String otp = random.ints(4, 0, 10).mapToObj(Integer::toString)
.reduce((a, b) -> a + b).get();
答案 2 :(得分:-1)
OTP只是固定长度的随机文本。只需一行代码即可完成(使用UUID)。请参见下面的示例,该示例将生成一个4个字符的OTP。
kernel.php