usuario que poner password ejemplo crear contraseña con asteriscos java security swing passwords

poner - jpasswordfield java que es



¿Por qué JPasswordField.getPassword() crea una cadena con la contraseña? (7)

** Encontré esto mientras buscaba una forma de mostrar realmente algunos datos confidenciales en un componente Swing sin usar un objeto String. Aparentemente no hay forma de hacerlo a menos que esté dispuesto a reescribir parte (¿todo?) De la API de Swing ... no va a suceder.

Puedes decirle a JPasswordField que muestre los caracteres llamando a field.setEchoChar(''/0'') . Esto conserva el resto de la protección ofrecida por JPasswordField (sin String , sin corte / copia).

JPasswordField de Swing tiene el método getPassword() que devuelve una matriz char. Mi comprensión de esto es que la matriz se puede poner a cero inmediatamente después de su uso para que no tenga cosas sensibles en la memoria por mucho tiempo. La forma antigua de recuperar la contraseña era usar getText() , que devuelve un objeto String, pero ha quedado en desuso.

Entonces, mi pregunta es por qué está siendo utilizada por Java durante el proceso de recuperación usando getPassword() ??? Para ser más claro, estaba depurando mi aplicación de prueba por algo más **, seguí las llamadas y me getText() ... getText() en JPasswordField y, por supuesto, se creó un bonito objeto String con mi contraseña y ahora está dando vueltas por la memoria.

Pruébalo por ti mismo:

public class PasswordTest() { public static void main(String[] args) { JFrame frame = new JFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JPasswordField passField = new JPasswordField(); pass.addActionListener(new ActionListener() { public ActionPerformed(ActionEvent evt) { char[] p = passField.getPassword(); // put breakpoint // do something with the array } }); frame.add(passField); frame.setVisible(true); frame.pack(); } }

Pregunta de seguimiento: ¿este uso "oculto" de getText() peligroso de alguna manera? Por supuesto, un atacante dedicado obtendrá su contraseña si ha comprometido el sistema, estoy hablando de uno menos dedicado;)

** Encontré esto mientras buscaba una forma de mostrar realmente algunos datos confidenciales en un componente Swing sin usar un objeto String . Aparentemente no hay forma de hacerlo a menos que esté dispuesto a reescribir parte (¿todo?) De la API de Swing ... no va a suceder.


En realidad, aquí está la implementación de Sun de getPassword() :

public char[] getPassword() { Document doc = getDocument(); Segment txt = new Segment(); try { doc.getText(0, doc.getLength(), txt); // use the non-String API } catch (BadLocationException e) { return null; } char[] retValue = new char[txt.count]; System.arraycopy(txt.array, txt.offset, retValue, 0, txt.count); return retValue; }

El único getText allí es una llamada a getText(int offset, int length, Segment txt) , que llama a getChars(int where, int len, Segment txt) , que a su vez copia caracteres directamente en el búfer del Segment . No se están creando Strings allí.

Luego, el búfer del Segment se copia en el valor de retorno y se pone a cero antes de que el método regrese.

En otras palabras: no hay una copia extra de la contraseña en ningún lado . Es perfectamente seguro siempre que lo use según las instrucciones.


Esto funciona para mí

String.valueOf(txtPass.getPassword())


Esto funciona para mí y te ayuda a construir una contraseña de Stringified:

String passText = new String(passField.getPassword());


La implementación de Swing es demasiado compleja para verificarla a mano. Quieres pruebas

public class Pwd { public static void main(String[] args) { java.awt.EventQueue.invokeLater(new Runnable() { public void run() { new javax.swing.JFrame("Pwd") {{ add(new javax.swing.JPasswordField() { @Override public String getText() { System.err.println("Awoooga!!"); return super.getText(); } { addActionListener( new java.awt.event.ActionListener() { public void actionPerformed( java.awt.event.ActionEvent event ) { // Nice. } } ); } }); setDefaultCloseOperation(DISPOSE_ON_CLOSE); pack(); setVisible(true); }}; } }); } }

Parece la cadena de comandos para el evento de acción (sin sentido) para mí. También habrá otra forma de causar el efecto.

Una VM vagamente moderna moverá objetos en la memoria de todos modos, por lo que borrar el char[] no necesariamente funciona.


Ok, mi mal ... Todas las campanas empezaron a sonar tan pronto como vi la llamada a getText () sin notar que en realidad la presenté con el oyente de Action, aquí hay una 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

Aquí está el código usado:

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(); } }

Y aquí está la salida de la consola:

Awhooa: secret secret

Y para la llamada real a getPassword (), tal vez me falta algo, pero ¿dónde está el buffer de Segment a cero? Veo una copia de matriz, pero no un cero. La matriz devuelta será puesta a cero por mí mismo, pero la matriz de Segment todavía está allí ...

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)); } }

Y el resultado:

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

(Pongo signos de interrogación allí porque no puedo pasar los caracteres no imprimibles)

-METRO


import javax.swing.*; public class login extends javax.swing.JFrame { MainProg main = new MainProg(); public login() { initComponents(); } /** * This method is called from within the constructor to initialize the form. * WARNING: Do NOT modify this code. The content of this method is always * regenerated by the Form Editor. */ @SuppressWarnings("unchecked") // <editor-fold defaultstate="collapsed" desc="Generated Code"> private void initComponents() { jLabel1 = new javax.swing.JLabel(); jLabel2 = new javax.swing.JLabel(); txtUser = new javax.swing.JTextField(); txtPassword = new javax.swing.JTextField(); jButton1 = new javax.swing.JButton(); setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); setTitle("Log In"); setBackground(new java.awt.Color(255, 204, 204)); setResizable(false); jLabel1.setText("Username:"); jLabel2.setText("Password:"); jButton1.setBackground(new java.awt.Color(204, 204, 204)); jButton1.setText("Enter"); jButton1.setOpaque(false); jButton1.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jButton1ActionPerformed(evt); } }); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) .addComponent(jButton1) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) .addGroup(layout.createSequentialGroup() .addComponent(jLabel1) .addGap(18, 18, 18) .addComponent(txtUser, javax.swing.GroupLayout.PREFERRED_SIZE, 210, javax.swing.GroupLayout.PREFERRED_SIZE)) .addGroup(layout.createSequentialGroup() .addComponent(jLabel2) .addGap(20, 20, 20) .addComponent(txtPassword)))) .addContainerGap(62, Short.MAX_VALUE)) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jLabel1) .addComponent(txtUser, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addGap(18, 18, 18) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jLabel2) .addComponent(txtPassword, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(jButton1) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); pack(); }// </editor-fold> private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) { String U = new String(this.txtUser.getText()); String P = new String(this.txtPass.gettext()); if(U.equals("Admin") && P.equals(Password)) { JOptionPane.showMessageDialog(null,"Login successful!","Message",JOptionPane.INFORMATION_MESSAGE); this.hide(); calculator.show(); } else { JOptionPane.showMessageDialog(null,"Invalid username and password","Message",JOptionPane.ERROR_MESSAGE); this.txtUser.setText(""); this.txtPassword.setText(""); } } /** * @param args the command line arguments */ public static void main(String args[]) { /* * Set the Nimbus look and feel */ //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) "> /* * If Nimbus (introduced in Java SE 6) is not available, stay with the * default look and feel. For details see * http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html */ try { for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) { if ("Nimbus".equals(info.getName())) { javax.swing.UIManager.setLookAndFeel(info.getClassName()); break; } } } catch (ClassNotFoundException ex) { java.util.logging.Logger.getLogger(login.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } catch (InstantiationException ex) { java.util.logging.Logger.getLogger(login.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } catch (IllegalAccessException ex) { java.util.logging.Logger.getLogger(login.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } catch (javax.swing.UnsupportedLookAndFeelException ex) { java.util.logging.Logger.getLogger(login.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } //</editor-fold> /* * Create and display the form */ java.awt.EventQueue.invokeLater(new Runnable() { public void run() { new login().setVisible(true); } }); } // Variables declaration - do not modify private javax.swing.JButton jButton1; private javax.swing.JLabel jLabel1; private javax.swing.JLabel jLabel2; private javax.swing.JTextField txtPassword; private javax.swing.JTextField txtUser; // End of variables declaration }