【问题标题】:Generating OTP through Java通过 Java 生成 OTP
【发布时间】:2018-03-24 03:36:52
【问题描述】:

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

【问题讨论】:

  • OTP 只是一个很短的真正随机数。用于验证新设备或路径。所以我建议你简单地使用 Random 类的 nextLong 方法,生成一个长整数而不是循环并为每个字符生成一个随机数。
  • @SamwellTarly 感谢请求您显示一个代码,以便我能掌握更多,前提是我必须生成 4 位数的 OTP
  • 这个问题更适合代码审查stackoverflow。

标签: java one-time-password


【解决方案1】:

正如评论指出的那样,一次性密码只是一个随机数或字符串。

查看您的代码,您正在使用Random 类。这对于随机序列的质量在很大程度上无关紧要的应用程序来说很好。然而,Random 的标准实现会产生一个高度可预测(自相关)的数字序列;见https://stackoverflow.com/a/38345694/139985。你应该改用SecureRandom

我怀疑您使用nextInt(numbers.length()) 会放大自相关...所以如果您继续使用Random,Samwell 的建议会有所帮助。

【讨论】:

  • 谢谢,请您出示代码位,以便我掌握更多
  • 嗯? SecureRandom 的 API 与 Random 几乎相同。查找 javadocs 并进行比较!
  • 当然,但是有一个小请求,您可以根据您的理解更改我上面写的一些实现,以便我能掌握更多
  • 您的请求被拒绝。说真的,如何生成一个 4 位十进制数字的随机数不是很明显吗?生成 0 到 9999 范围内的单个随机数,并将其转换为带有前导零的字符串。
【解决方案2】:

使用 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(); 

【讨论】:

    【解决方案3】:

    OTP 只是一个固定长度的随机文本。它可以通过一行代码来实现(使用UUID)。请参见下面的示例,该示例生成 4 个字符的 OTP。

    UUID.randomUUID().toString().substring(0, 4)
    

    【讨论】:

      猜你喜欢
      • 2017-03-15
      • 1970-01-01
      • 2020-10-04
      • 1970-01-01
      • 1970-01-01
      • 2014-04-16
      • 2011-01-30
      • 2019-09-06
      • 2012-08-09
      相关资源
      最近更新 更多