通过Java生成OTP

时间:2018-03-24 03:36:52

标签: java one-time-password

我开发了以下程序来生成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));
    }
}

3 个答案:

答案 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