【问题标题】:Password masking does not terminate the program when needed密码屏蔽不会在需要时终止程序
【发布时间】:2010-10-06 10:42:05
【问题描述】:

我开发了以下应用程序,其中我需要在用户输入错误 PIN 三次后屏蔽 PIN 并终止程序。但是,仅当我在开头关闭 stopThread 时程序才会终止(我在下面的代码中对其进行了注释),但是当我这样做时,所有三个机会都不会发生密码屏蔽。但是,当我在显示登录成功屏幕之前关闭 stopThread 时,程序不会终止。我需要使用 ctrl+c 来结束程序。

非常感谢任何帮助。

boolean stopThread = false;
boolean hideInput = false;
boolean shortMomentGone = false;
public static double userBal=0.0D;

public void run(){
    try{
        sleep(500);
    } catch(InterruptedException e){
    }
    shortMomentGone = true;
    while(!stopThread){
        if(hideInput){
            System.out.print("\b*");
        }
        try{
            sleep(1);
        } catch(InterruptedException e){
        }
    }
}

public static final int NB_OF_TRIES = 3;        

public void validatePin(){
    BankAccount getAll=new BankAccount();
String pin="";
    getAll.Login();
    Login hideThread =new Login();
    hideThread.start();
    BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
    try{    
    do{

        } while(hideThread.shortMomentGone == false  );          
    // Now the hide thread should begin to overwrite any input with "*"
        hideThread.hideInput = true;            // Read the PIN
        System.out.println("\nPIN:");

    boolean pinMatch = false;
        int i = 0;

    while(!pinMatch && i < NB_OF_TRIES) {
        hideThread.hideInput = true;
        pin = in.readLine();
    i++;
        //hideThread.stopThread = true;       //Program terminates after third attempt 
                                              //PIN masking is stopped, if uncommented
        System.out.print("\b \b");        
        if(pin.equals(" ")){
    System.out.println("Please do not leave unnecessary spaces!");
    getAll.Login();
    }else if(pin.equals("")){
    System.out.println("Please do not press the enter key without entering the PIN!");
        getAll.Login();
    }

    FileInputStream fileinputstream = new FileInputStream(".\\AccountInfo.txt");
        DataInputStream datainputstream = new DataInputStream(fileinputstream);
        BufferedReader bufferedreader1 = new BufferedReader(new InputStreamReader(datainputstream));

    do
        {
            String s1;
            if((s1 = bufferedreader1.readLine()) == null)
            {
                break;
            }
            if(s1.trim().charAt(0) != '#')
            {
                String as[] = s1.split(" ");
                if(pin.equals(as[0]))
                {          
                    System.out.println("You have login!");
                    String s2 = as[2];
                    userBal = Double.parseDouble(s2);                       
                    getAll.balance = userBal;
                hideThread.stopThread = true;
                    getAll.MainMenu();
        System.exit(0);
                }else if(pin != as[0]){
        System.out.println("Invalid PIN!");
        getAll.Login();           
        System.out.println("\n NOTE :- You are only allowed to enter the PIN THREE times. The number of tries remaining before your card is blacklisted are "+i + "\n Please re-enter your PIN");
                }
            }
        } while(true);
        datainputstream.close();    
    }//End of While Loop

    }catch(Exception exception)
    {
        System.err.println((new StringBuilder()).append("Error: ").append(exception.getMessage()).toString());
    }//End of try-catch block    
}

【问题讨论】:

    标签: java passwords masking


    【解决方案1】:

    在 java.io.Console 中有一个 readPassword() 方法,使用它。为什么你需要一个单独的线程?这让一切都变得太复杂了。

    关于您的问题,为什么这不会关闭:如果您不设置 isTrue volatile 或同步对 isTrue(getter/setter)的访问,Java 可能会将 while(isTrue){} 优化为 if(isTrue) { while(true) { } } 之类的东西。这种优化称为提升,并在 Effective Java SE,第 66 项中进行了解释。

    这是一篇准确解释您的问题的文章:回显 * 而不是空格。 http://java.sun.com/developer/technicalArticles/Security/pwordmask/ 他们也在走复杂的路,但它确实有效。我更喜欢空格而不是星号,因为这是更简单的方法。不回显 * 是 *nix 标准 afaik。

    【讨论】:

    • 其实我用了readPassword方法,不过是用空格代替了字符,但是我需要它来显示一个常用的符号。这就是我使用这种技术的原因
    • 整个解决方案太复杂了。
    【解决方案2】:

    实际上,经过我的分析之后,我意识到系统不会终止的原因是因为它没有保存在正确的位置。因此,解决方案是在 while 循环关闭后立即结束程序,然后一切正常。

            } while(true);
            datainputstream.close(); 
     }//End of While Loop
         System.exit(0);  // After the system is closed the program would terminate after the third attempt
        }catch(Exception exception)
        {
            System.err.println((new StringBuilder()).append("Error: ").append(exception.getMessage()).toString());
        }//End of try-catch block
    

    【讨论】:

      猜你喜欢
      • 2018-04-25
      • 2016-10-12
      • 2011-03-25
      • 2014-02-05
      • 2011-02-01
      • 2017-10-02
      • 2011-11-17
      • 1970-01-01
      相关资源
      最近更新 更多