一次性密码安全风险

发布于 2024-12-09 06:01:35 字数 177 浏览 1 评论 0原文

我们正在开发一个 Web 应用程序,用户必须输入一次性密码(我们通过电子邮件发送给用户)才能完成操作。然而,如果恶意用户开发了一个机器人并猜测了我们生成一次性密码的模式,他可以输入一些随机电子邮件 ID,甚至不需要查看电子邮件就可以确认交易。这样他就可以通过错误确认来攻击系统。有人可以告诉我们人们如何处理这个问题吗?

谢谢

We are developing a web application where user has to input a One Time Password (which we email to the users) to complete an operation. However, if a malicious user develops a bot and guesses the pattern in which we generate the One Time Password, he can input some random email id and by not even looking at the email he can confirm the transaction. That way he can attack the system with false confirmations. Can someone please let us know how people deal with this?

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

蹲墙角沉默 2024-12-16 06:01:36

如果您的随机一次性密码与常规密码具有相同的熵,那么这应该与任何其他密码解决方案一样好。

这是一个示例密码生成片段,它应该是相当不可预测的:

import java.security.SecureRandom;
import java.util.Random;

class Test {

    public static String generatePassword() {
        String chars = "abcdefghijklmnopqrstuvwxyz"
                     + "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
                     + "0123456789!@%$%&^?|~'\"#+="
                     + "\\*/.,:;[]()-_<>";

        final int PW_LENGTH = 20;
        Random rnd = new SecureRandom();
        StringBuilder pass = new StringBuilder();
        for (int i = 0; i < PW_LENGTH; i++)
            pass.append(chars.charAt(rnd.nextInt(chars.length())));
        return pass.toString();
    }

    public static void main(String[] args) {
        System.out.println(generatePassword());
        System.out.println(generatePassword());
        System.out.println(generatePassword());
    }
}

输出:

Qp';Md#93Dxh\0|%%Ny7
oqvntn2).~W@%P'EM*AS
WEo2sz2Sm~a'm=Ss&Lu[

If your random one-time passwords have the same entropy as regular passwords, this should be just as fine as any other password solution.

Here's an example password generation snippet which should be fairly unpredictable:

import java.security.SecureRandom;
import java.util.Random;

class Test {

    public static String generatePassword() {
        String chars = "abcdefghijklmnopqrstuvwxyz"
                     + "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
                     + "0123456789!@%$%&^?|~'\"#+="
                     + "\\*/.,:;[]()-_<>";

        final int PW_LENGTH = 20;
        Random rnd = new SecureRandom();
        StringBuilder pass = new StringBuilder();
        for (int i = 0; i < PW_LENGTH; i++)
            pass.append(chars.charAt(rnd.nextInt(chars.length())));
        return pass.toString();
    }

    public static void main(String[] args) {
        System.out.println(generatePassword());
        System.out.println(generatePassword());
        System.out.println(generatePassword());
    }
}

Output:

Qp';Md#93Dxh\0|%%Ny7
oqvntn2).~W@%P'EM*AS
WEo2sz2Sm~a'm=Ss&Lu[

相思碎 2024-12-16 06:01:36

我从你的问题描述中猜测,你生成的“一次性密码”实际上是某种形式的粗加密,你可以逆转该过程以找出他们所指的帐户。

这是错误的方法,一次性密码需要是随机的,因此无法根据电子邮件地址计算密码。您需要将一次性密码(最好是经过哈希处理)与帐户信息一起存储在数据库中,并使用它进行查找。

I'm guessing from your question description that the "one time password" you're generating is actually some form of crude encryption where you reverse the process in order to figure out which account they're referring to.

This is the wrong approach, the one time password needs to be random so there's no possible way to compute the password based on the email address. You'll need to store the one time password (preferably hashed) with the account info in the database and use that for looking up.

云柯 2024-12-16 06:01:36

使用高熵源生成密码 - 在 unix 中尝试 /dev/urandom - 这将有效地为您提供一次性密码。

Generate your passwords using a high entropy source - in unix try /dev/urandom - that will effectively give you one-time passwords.

苦笑流年记忆 2024-12-16 06:01:36

不要这样做。向他们发送一个URL链接,其中包含一个巨大的密码(安全票证)作为URL参数,并安排你的结尾,以便如果该参数存在并且正确(i)他们会登录并且(ii) ) UUID 的有效性立即终止或在发送后一两天内终止。可能需要一些操作,具体取决于您的容器,但它更安全。我使用 java.util.UUID 来实现这一点,很好而且很长。

Don't do it. Send them a URL link with a huge password (security ticket) in it as a URL argument, and arrange your end so that if that argument is present and correct (i) they are logged in and (ii) the validity of the UUID ceases, either immediately or within a day or two of sending it. May take a bit of doing depending on your container but it's far more secure. I use java.util.UUID for this, nice and long.

月野兔 2024-12-16 06:01:36

你是对的,你的计划中有一个很大的安全漏洞,但你发现了错误的漏洞!

您的问题是您通过电子邮件发送出去 - 电子邮件不安全。

至于猜测问题,只要使用足够长的密码,统计上应该是不可能的。当人们猜错 100 次后,你可能想将他们拒之门外。

我见过的一个技巧是要求用户提供 Paypal 或银行帐号。然后您可以随机存入一些金额。因此,他们看到的存款金额为 34、91 和 82 美分。然后他们使用这些数字作为密码!很聪明吧?

You are correct you have a big security hole in the scheme but you identified the wrong hole!

Your problem is that you email it out-- email isn't secure.

As for guessing the problem that should be statistically impossible as long as you use a long enough password. You might want to lock people out after they guess wrong 100 times.

One trick I've seen is asking a user for a Paypal or bank account number. You then make a few deposits for random amounts. So they see deposits for say 34, 91, and 82 cents. They then use those numbers as a password! Pretty clever huh?

烧了回忆取暖 2024-12-16 06:01:36

实施一个一次性密码,该密码在计算上无法猜测。

例如,使用随机字符串生成器生成一个 15 个字符长的字符串,其中使用大写字母、小写字母和数字的池。

这会产生 62^15 种可能的组合,这对于暴力程序来说是极难破解的。

Implement a one-time password which is not computationally feasible to guess.

For example, use a random string generator to generate a string 15 characters long, using a pool of uppercase letters, lowercase letters, and numbers.

This results in 62^15 possible combinations, which would be extremely difficult for a brute force program to crack.

披肩女神 2024-12-16 06:01:36

使用 6 位随机数作为 OTP 并不存在安全风险,只要您在首次使用后使 OTP 失效。一次猜出 6 位数字几乎是不可能的。而且由于您只能尝试一次,因此也不用担心暴力破解。只需确保生成真正的随机数,例如使用 SecureRandom。

因此,要采取的步骤:

  1. 列表项
  2. 生成 6 位随机数 OTP
  3. 将其与帐户关联(例如,用户输入电子邮件和 OTP)
  4. 在给定用户电子邮件的每次身份验证尝试中,使 OTP 无效,无论登录是否成功不

使用 Java,您可以使用以下方法生成 OTP:

public static final String getOTP(int length) {

    Random r = new SecureRandom();
    return String.valueOf(r.nextInt((int)Math.pow(10, length)));
}

希望这是有道理的。

Having a 6 digit random number as an OTP is not a security risk as long as you invalidate the OTP after the first use. To guess a 6 digit number in a single try is neigh on impossible. And since you only get one try, brute-force isn't something to worry about either. Just make sure you generate a truly random number, e.g. using SecureRandom.

So, steps to take:

  1. List item
  2. Generate a 6-digit random number OTP
  3. Correlate it to an account (so e.g. user enters email and OTP)
  4. On each auth attempt of a given user email, invalidate the OTP, whether the login was successful or not

Using Java, you could use the following method to generate the OTP:

public static final String getOTP(int length) {

    Random r = new SecureRandom();
    return String.valueOf(r.nextInt((int)Math.pow(10, length)));
}

Hope that makes sense.

╰◇生如夏花灿烂 2024-12-16 06:01:35

只需使用没有模式的随机密码。优点是如果密码在邮件中可单击,则可以使密码更长,因为用户不必键入密码。

Just use random password without patterns. The advantage is you can make the password longer if it is clickable in the mail because the user doesn't have to type it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文