2013-07-17 2 views
1

문자열이 아닌 API을 사용하여 JPasswordField의 암호를 클립 보드로 잘라내거나 복사하는 방법. 이로써 해커가 암호를 볼 수있는 창을 닫습니다.JPasswordField의 텍스트를 문자 배열로 잘라내거나 복사하는 방법은 무엇입니까?

이 링크 https://stackoverflow.com/a/8885343/2534090에 따르면 문자 배열은 텍스트와 다릅니다.

public static void main(String[] args) { 
    Object pw = "Password"; 
    System.out.println("String: " + pw); 

    pw = "Password".toCharArray(); 
    System.out.println("Array: " + pw); 
} 

인쇄 :

String: Password 
Array: [[email protected] 

내가 뭘 클립 보드에 있어야 할 것은 [[email protected]입니다하지만 Password

내가 클립 보드에 내용을 복사 StringSelection를 사용하여 시도했지만 생성자 소요 String은 변경 불가능하며 안전하지 않습니다.

+1

질문을 읽는 동안 정말 혼란 스럽습니다. JPasswordField의 char-Array를 가져 와서 이미이 메서드를 찾았습니다. 비밀번호로 정확히 무엇을하고 싶습니까? – snrlx

+0

이것은 당신에게 몇 가지 머리를 줄 수 있습니다 : http://stackoverflow.com/questions/17706393/how-do-enable-cut-copy-in-jpasswordfield –

+0

참조하면 문자 배열을 인쇄, 당신은 다른 출력을 얻을 때 getText()를 사용하여 텍스트를 가져옵니다 (즉, 암호). 이제 내 질문은 다른 출력을 클립 보드로 가져 오는 방법입니다! – user12458

답변

1

사용자 지정 TransferHandler을 사용하면이 작업을 수행 할 수 있습니다.

Using and Creating a Data Flavor의 스윙 튜토리얼의 섹션에 따르면, 클립 보드에 기록 된 객체로 char []를 사용할 수 있어야합니다.

그러나 작동하지 않아서 클립 보드에 StringBuilder를 작성하는 결과가 발생했습니다. 나는 char []를 사용하려고 시도한 코드를 주석 처리했는데 다른 사람이 내가 잘못한 것을 알아낼 수 있습니다.

import java.awt.*; 
import java.awt.datatransfer.*; 
import java.awt.event.*; 
import javax.swing.*; 
import javax.swing.text.*; 
import java.io.*; 

public class PasswordHandler extends TransferHandler 
{ 
// public final static DataFlavor CHAR_ARRAY_FLAVOR = new DataFlavor(char[].class, "Char Array"); 
    public final static DataFlavor CHAR_ARRAY_FLAVOR = new DataFlavor(StringBuilder.class, "StringBuilder"); 

    @Override 
    public int getSourceActions(JComponent c) 
    { 
     return COPY; 
    } 

    @Override 
    public Transferable createTransferable(final JComponent c) 
    { 
     return new Transferable() 
     { 
      @Override 
      public Object getTransferData(DataFlavor flavor) 
      { 
       JPasswordField textField = (JPasswordField)c; 
//    return textField.getPassword(); 
       return new StringBuilder(textField.getText()); 
      } 

      @Override 
      public DataFlavor[] getTransferDataFlavors() 
      { 
       DataFlavor[] flavors = new DataFlavor[1]; 
       flavors[0] = CHAR_ARRAY_FLAVOR; 
       return flavors; 
      } 

      @Override 
      public boolean isDataFlavorSupported(DataFlavor flavor) 
      { 
       return flavor.equals(CHAR_ARRAY_FLAVOR); 
      } 
     }; 
    } 

    @Override 
    public boolean canImport(TransferSupport support) 
    { 
     boolean canImport = support.isDataFlavorSupported(CHAR_ARRAY_FLAVOR); 
     return canImport; 
    } 

    @Override 
    public boolean importData(TransferSupport support) 
    { 
//  char[] password; 
     StringBuilder password; 

     try 
     { 
//   password = (char[])support.getTransferable().getTransferData(CHAR_ARRAY_FLAVOR); 
      password = (StringBuilder)support.getTransferable().getTransferData(CHAR_ARRAY_FLAVOR); 
     } 
     catch (Exception e) 
     { 
      e.printStackTrace(); 
      return false; 
     } 

     JPasswordField textField = (JPasswordField)support.getComponent(); 
     textField.setText(password.toString()); 
     return true; 
    } 

    private static void createAndShowUI() 
    { 
     JPasswordField tf1 = new JPasswordField(10); 
     JPasswordField tf2 = new JPasswordField(10); 

     TransferHandler handler = new PasswordHandler(); 
     tf1.setTransferHandler(handler); 
     tf2.setTransferHandler(handler); 
     tf1.putClientProperty("JPasswordField.cutCopyAllowed",true); 
     tf2.putClientProperty("JPasswordField.cutCopyAllowed",true); 

     JFrame frame = new JFrame("Password Copy"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.add(tf1, BorderLayout.WEST); 
     frame.add(tf2, BorderLayout.EAST); 
     frame.add(new JTextField(), BorderLayout.SOUTH); 
     frame.pack(); 
     frame.setLocationByPlatform(true); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) 
    { 
     EventQueue.invokeLater(new Runnable() 
     { 
      public void run() 
      { 
       createAndShowUI(); 
      } 
     }); 
    } 
} 

코드는 암호 필드의 전체 텍스트를 사용합니다. 선택한 문자 만 원하는 경우 getTransferData() 메서드를 수정하여 선택한 문자를 StringBuilder에만 추가해야합니다.

관련 문제