安全!我想知道是否有任何方法可以使我的程序更安全(新手程序员)

时间:2014-04-02 15:38:11

标签: java security exception

我有程序随机生成用户名文本文件的密码。我想知道如何检查并确保用户没有输入无效的输入和抛出错误。我不明白如何循环检查有效输入。

import java.util.Random;
import java.io.File;
import java.util.Scanner;
import java.io.PrintStream;
import java.lang.Math;

//Create class PasswordProgram
public class PasswordProgram {
    public static void main(String[] args) throws Exception {
        Random rand = new Random();

        // Read in the text file with usernames
        File infile = new File(args[0]);
        File outfile = new File("PasswordList.txt");

        Scanner kbd = new Scanner(System.in);
        Scanner Infile = new Scanner(infile);

        // Allowing All types of characters to be added
        PrintStream Outfile = new PrintStream(outfile);
        String uppers = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        String lowers = "abcdefghijklmnopqrstuvwxyz";
        String digits = "0123456789";
        String symbols = "`~!$%^&*()_+{}|:<>?/.,';][=-";
        String total = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
                + "abcdefghijklmnopqrstuvwxyz"
                + "0123456789`~!$%^&*()_+{}|:<>?/.,';][=-";

        outfile.setReadable(true, true);

        // Ask user how many uppercase letters they want in their password
        System.out.print("Minumum uppercase: ");
        int Uppers = kbd.nextInt();

        // Ask user how many lowercase letters they want in their password
        System.out.print("Minumum lowercase: ");
        int Lowers = kbd.nextInt();

        // Ask user how many digits they want in their password
        System.out.print("Minumum digits: ");
        int Digits = kbd.nextInt();

        // Ask user how many symbols they want in their program
        System.out.print("Minumum symbols: ");
        int Symbols = kbd.nextInt();

        // Ask user how many total characters they want their password
        System.out.print("Minumum total characters: ");
        int Total = kbd.nextInt();
        char[] password = new char[Total];

        String user;
        int i, j, k;
        char temp;

        // As long as there is more usernames add more passwords
        while (Infile.hasNext()) {
            user = Infile.next();

            // Create random uppercase letters
            for (i = 0; i < Uppers; i++) {
                password[i] = uppers.charAt(Math.abs(rand.nextInt()) % 26);
            }

            // Create random lowercase letters and add them to uppercase
            for (i = Uppers; i < (Uppers + Lowers); i++) {
                password[i] = lowers.charAt(Math.abs(rand.nextInt()) % 26);
            }

            // Create random digits and add them to previous uppercase and
            // lowercase
            for (i = Uppers + Lowers; i < (Uppers + Lowers + Digits); i++) {
                password[i] = digits.charAt(Math.abs(rand.nextInt()) % 10);
            }

            // Create random symbols and add them to previous uppercase,
            // lowercase, and digits
            for (i = Uppers + Lowers + Digits; i < (Uppers + Lowers + Digits + Symbols); i++) {
                password[i] = symbols.charAt(Math.abs(rand.nextInt()) % 26);
            }

            // Create total characters and make sure the password as at least
            // that length with uppercase, lowercase, digits, and symbols
            for (i = Uppers + Lowers + Digits + Symbols; i < Total; i++) {
                password[i] = total.charAt(Math.abs(rand.nextInt()) % 88);
            }

            // Print the generated passwords for each username
            System.out.println(user + " " + (new String(password)));
            Outfile.println(user + " " + (new String(password)));
        }
    }
}

2 个答案:

答案 0 :(得分:1)

  1. 明文密码永远不是一件好事。先把它们哈希。

  2. 为什么要将所有用户名/密码保存在文本文件中?使用像MySQL这样的DBMS。您可以使用MySQL JDBC Driver在Java中轻松实现它。

  3. 如果非常有必要使用文本文件,请循环访问用户名文件并使用计数器。找到用户名后,循环访问密码文件,直到到达特定行。然后,您可以比较两个密码。

  4. 如果密码错误,请使用

    if(!input.equals(password)) { throw new Exception("Wrong password!"); }

答案 1 :(得分:0)

另一个建议:
你有什么理由提出所有这些问题来生成用户密码? 随机密码很难记住,询问放入其中的特殊字符的数量将无济于事。

对于生成的密码,我建议您制定自己的指南并根据该密码生成密码,而不是询问所有这些提示。

但现代密码通常是单向散列加密的,因此您实际上只存储加密形式的密码,当用户再次输入密码时,您再次对其进行加密,然后将其与加密的存储密码进行匹配。
这有一个很大的好处,即密码不会被盗,即使加密的哈希被盗,它也不能再被“解密”。

你甚至不需要任何特殊字符,但我建议强制使用最小长度的7-8个字符 这里是一个关于如何制作加密哈希的示例代码

MessageDigest digest = MessageDigest.getInstance("MD5");
digest.update("CUSTOMSTRING"+pass.getBytes(), 0, 12+pass.length());
String md5 = new BigInteger(1, digest.digest()).toString(16);

此代码将从任何密码中生成一个16字节的MD5哈希,它会向其添加一个所谓的“Salt”(示例中为“CUSTOMSTRING”),这使得如果有人通过暴力获取原始密码非常困难窃取哈希而无需访问代码。

我总是讨厌要求你在密码中使用大写字符或特殊字符的网站,因为这会让我忘记密码。这些天没有猜到密码,也可以检测到蛮力。

要点:
不要根据用户提示生成密码,而是让用户选择一个。只需要一个可以轻松检查的最小长度。并且不要存储密码,只需存储加密和盐渍哈希 如果发生安全漏洞(数据库被盗),攻击者只能有限地使用密码哈希值。