Why does JPasswordField.getPassword() create a String with the password in it?

前端 未结 7 2026
长发绾君心
长发绾君心 2020-11-28 10:52

Swing\'s JPasswordField has the getPassword() method that returns a char array. My understanding of this is that the array can be zeroed immediately after use so that you do

7条回答
  •  野趣味
    野趣味 (楼主)
    2020-11-28 11:41

    Ok, my bad... All the bells started ringing as soon as I saw the call to getText() without noticing that it was actually introduced by me with the Action listener here's a stacktrace

    PasswordTest$1.getText() line: 14   
    PasswordTest$1(JTextField).fireActionPerformed() line: not available    
    PasswordTest$1(JTextField).postActionEvent() line: not available    
    JTextField$NotifyAction.actionPerformed(ActionEvent) line: not available    
    SwingUtilities.notifyAction(Action, KeyStroke, KeyEvent, Object, int) line: not available
    

    Here is the code used:

     import java.awt.event.*;
    
     import javax.swing.*;
    
     public class PasswordTest {
            public static void main(String[] args) {
                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                final JPasswordField passField = new JPasswordField() {
                    @Override
                    public String getText() {
                        System.err.println("Awhooa: " + super.getText()); //breakpoint
                        return null;
                    }
                };
                passField.addActionListener(new ActionListener() {
                    public void actionPerformed(ActionEvent evt) {
                        char[] p = passField.getPassword();
                        System.out.println(p);
                    }
                });
                frame.add(passField);
                frame.setVisible(true);
                frame.pack();
            }
        }
    

    And here is the console output:

    Awhooa: secret
    secret
    

    And for the actual call to getPassword(), maybe I am missing something, but where is Segment's buffer zeroed? I see an array copy, but not a zeroing. The returned array will be zeroed by myself, but Segment's array is still there...

    import java.util.Arrays;
    
    public class ZeroingTest {
        public static void main(String[] args) {
            char[] a = {'a','b','c'};
            char[] b = new char[a.length];
            System.arraycopy(a, 0, b, 0, b.length);
            System.out.println("Before zeroing: " + Arrays.toString(a) + " " + Arrays.toString(b));
            Arrays.fill(a, '\0');
            System.out.println("After zeroing: " + Arrays.toString(a) + " " + Arrays.toString(b));
        }
    }
    

    And the output:

    Before zeroing: [a, b, c] [a, b, c]
    After zeroing: [?, ?, ?] [a, b, c]
    

    (I put question marks there because I cannot past unprintable characters)

    -M

提交回复
热议问题