JPasswordField

Status
Nicht offen für weitere Antworten.

homer65

Top Contributor
Ich benutze öfters code der folgenden Art:
[Java]
JPasswordField tf1 = new JPasswordField(10);
...
tf1.getText();
[/Java]
Dann heißt es immer tf1.getText() sei deprecated. Was muß man denn stattdessen benutzen, wenn man das Passwort im Klartext bhaben möchte?
 

homer65

Top Contributor
Also wäre jetzt folgendes richtig:
[Java]
JPasswordField tf1 = new JPasswordField(10);
...
char[] pw = tf1.getPassword();
String passwort = new String(pw);
[/Java]
Warum so umständlich? Da hätte man doch auch einfach die getText() Methode behalten können. Oder hatt das einem tieferen Sinn, der sich mir nicht erschließt?
 

The_S

Top Contributor
Hat nen tieferen Sinn, der sich dir scheinbar nicht erschließt. Ein String liegt komplett so und sofort auslesbar im Arbeitsspeicher => Sicherheitsrisiko.
 
S

SlaterB

Gast
und das char[] nicht? war das nicht eher was hinsichtlich String-Cache in Java?
 

The_S

Top Contributor
Achja, da war was ... müsste man mal schnell recherchieren. Aufjedenfall ist es ein Sicherheitsrisiko.
 

Ebenius

Top Contributor
Hat also doch nix mit caching (bzw. dem Literal-Pool) zu tun, sondern damit, dass ich das char-Array nach der Verwendung wieder bereinigen kann, der String aber unverändert darauf warten muss, dass ihn irgendwann der GC erwischt. Also trifft eher The_S' Erklärung zu. Oder hab ich das jetzt falsch verstanden?

Ebenius
 
S

SlaterB

Gast
> der String aber unverändert darauf warten muss, dass ihn irgendwann der GC erwischt.

es erwischt ihn nicht wegen des String-Caches

edit:
jedenfalls potentiell nicht so schnell
 
Zuletzt bearbeitet von einem Moderator:
G

Gast2

Gast
Also wäre jetzt folgendes richtig:
[Java]
JPasswordField tf1 = new JPasswordField(10);
...
char[] pw = tf1.getPassword();
String passwort = new String(pw);
[/Java]

aber wenn man es so macht hat man doch einen String den man auslesen kann oder?
Oder dann einfach der benutzung das char array und den string auf null setzen??
 
S

SlaterB

Gast
new String() ist das, was hier vermieden werden soll, das wäre also genauso schlimm, korrekt

char[] auf null setzen ist schon recht gut, sollte relativ zügig vom GC gelöscht werden,
noch besser aber die Felder im Array auf 0 setzen, das passiert nun wirklich direkt bei Codeausführung
und mit einem leeren Array kann bis auf die Länge niemand mehr was anfangen,

String = null; kann potentiell lange Zeit nix bringen, wobei ich persönlich aber das Cachen von Strings in Java nicht im Detail kenne
 

Ebenius

Top Contributor
> der String aber unverändert darauf warten muss, dass ihn irgendwann der GC erwischt.

es erwischt ihn nicht wegen des String-Caches

edit:
jedenfalls potentiell nicht so schnell
Sorry, dass ich das nochmal aufgreife. Was ist "String-caching"? Den Begriff kenne ich nicht und er geht auch nicht aus der Seite oben hervor. Ich kenne den Literal-Pool und mit dem hat's nichts zu tun. Bitte erklär's mir.

Nachtrag: Soweit ich weiß gibt es keine Sonderbehandlung für Strings, außer den Literal-Pool. In diesen werden nur String-Literale und mit String.intern() explizit in den Pool geworfene String-Instanzen gehalten. Der einzige logische Grund, getPassword() zu bevorzugen, ist der, das char-Array nach Verwendung mit 0en (oder anderen Werten) zu überschreiben. Die char-Array-Referenz auf null zu setzen hat genau die selbe Konsequenz wie die Referenz auf den String auf null zu setzen: Irgendwann räumt der GC auf (ggf. niemals, wenn man die VM entsprechend initialisiert) und dann kann man das Passwort zu jeder Zeit aus dem Speicher lesen.

Ebenius
 
Zuletzt bearbeitet:

eRaaaa

Top Contributor
Hi,

dann hab ich direkt auch noch eine Frage :)
Wie und wo liegt dann das "echte" Passwort, also das, mit dem ich die Benutzereingabe überprüfen möchte? Denn wenn dieses, auch irgendwo als String vorliegt, wäre dies ja dann genauso auch Blödsinn oder?!

Gruß
 
S

SlaterB

Gast
@Ebenius:
Literal-Pool = Menge von vorhandenen String-Objeken = String-Cache

und auf die Tour sage ich nichts weiter, wenn du Argumente dagegen hast dann erkläre doch deine Sichtweise

--------

@eRaaaa
stimmt,

wie und wo liegt dann das "echte" Passwort vorliegt war bisher noch nicht das Thema,
in Sicherheitsbetonten-Programm sicher nirgendwo sondern nur der Hashwert dazu,
 
S

SlaterB

Gast
also, nochmal neu sortiert:
String wie char[] werden vom GC gelöscht, wann die Zeit dafür ist, es gibt keinen Cache für die dynamisch zusammengebauten Strings,
der Literal-Pool ist nur für Strings aus dem Quellcode

der GC kann sich Zeit lassen, bei char[] hat man aber die Möglichkeit, das Array selber zu leeren (alles auf 0 setzen)

edit: wie auch in deinem Nachtrag, sag ich doch, erkläre es einfach ;)
 

Ebenius

Top Contributor
und auf die Tour sage ich nichts weiter, wenn du Argumente dagegen hast dann erkläre doch deine Sichtweise
:autsch: Bin ich Dir auf den Schlips getreten? Das war nicht meine Absicht! Hast meinen Nachtrag oben noch gelesen?

Der Literal-Pool beinhaltet alle String-Instanzen die im ByteCode als Literal vorkommen. Dafür ist er da. Was ein Literal ist, entscheidet der Compiler. Beispiel:
Java:
/** das Literal "abc" liegt im Pool */
final String s1 = "abc";

/**
 * das Literal "def" liegt im Pool, die Instanz auf die die Referenz s2
 * verweist liegt nicht im Pool
 */
final String s2 = new String("def");

/**
 * die Literale "a", "b" und "ab" liegen im Pool, da der Compiler die
 * String-Konkatenation von Literalen selbst ausführt
 */
final String s3 = "a" + "b";

/**
 * die Literale "a", "b" und "a1b" liegen im Pool, da auch 1 ein Literal ist
 */
final String s4 = "a" + 1 + "b";

Wenn Du aber einen Text in ein JTextComponent-Derivat eingibst, von einer URL lädst, per Random erzeugst, etc., dann handelt es sich nicht um Literale. Deswegen gibt es auch keinen Passworttext im Literal-Pool, es sei denn jemand ruft String.intern() auf dem Passwort-String auf; was natürlich niemand macht.

Ich halte die namentliche Unterscheidung zwischen einem Cache und einem Literal-Pool für sehr wichtig. Cache bedeutet, dass eine gewisse Menge an Information zeitlich oder mengenmäßig begrenzt zur Wiederverwendung vorgehalten wird. Der Literal-Pool enthält alle Literale ab ihrer ersten Verwendung; diese Literale verlassen den Pool nie wieder.

Nachtrag
wie auch in deinem Nachtrag, sag ich doch, erkläre es einfach ;)
Du bist einfach zu schnell. :) Auch dieser Beitrag bezog sich noch auf den Vorgänger. :-D

Ebenius
 
Zuletzt bearbeitet:
S

SlaterB

Gast
habe ich ja inzwischen verstanden, siehe vorheriges Post,

und die Antwort zeigt nun genau, dass du alles dazu wußtest, viel besser als ich,
da konnte ich schon erahnen zu was deine pseudo-freundlichen 'Bitte erklär's mir.'-Postings führen:
ich erklär nochmal meine falsche Sichtweise genauer und dann kannst du sie noch genauer widerlegen

ist nicht bös gemeint, nur unnötiges Vorgehen welches mich immer total nervt
 
G

Gast2

Gast
:autsch: Bin ich Dir auf den Schlips getreten? Das war nicht meine Absicht! Hast meinen Nachtrag oben noch gelesen?

Der Literal-Pool beinhaltet alle String-Instanzen die im ByteCode als Literal vorkommen. Dafür ist er da. Was ein Literal ist, entscheidet der Compiler. Beispiel:
Java:
/** das Literal "abc" liegt im Pool */
final String s1 = "abc";

/**
 * das Literal "def" liegt im Pool, die Instanz auf die die Referenz s2
 * verweist liegt nicht im Pool
 */
final String s2 = new String("def");

/**
 * die Literale "a", "b" und "ab" liegen im Pool, da der Compiler die
 * String-Konkatenation von Literalen selbst ausführt
 */
final String s3 = "a" + "b";

/**
 * die Literale "a", "b" und "a1b" liegen im Pool, da auch 1 ein Literal ist
 */
final String s4 = "a" + 1 + "b";

Wenn Du aber einen Text in ein JTextComponent-Derivat eingibst, von einer URL lädst, per Random erzeugst, etc., dann handelt es sich nicht um Literale. Deswegen gibt es auch keinen Passworttext im Literal-Pool, es sei denn jemand ruft String.intern() auf dem Passwort-String auf; was natürlich niemand macht.

Ich halte die namentliche Unterscheidung zwischen einem Cache und einem Literal-Pool für sehr wichtig. Cache bedeutet, dass eine gewisse Menge an Information zeitlich oder mengenmäßig begrenzt zur Wiederverwendung vorgehalten wird. Der Literal-Pool enthält alle Literale ab ihrer ersten Verwendung; diese Literale verlassen den Pool nie wieder.

Nachtrag

Du bist einfach zu schnell. :) Auch dieser Beitrag bezog sich noch auf den Vorgänger. :-D

Ebenius

also wenn ich das char array in ein String objekt umwandel und nach der Verwendung gleich einen anderen wert gebe... dann müsse es doch auch gehen oder?
Java:
        String password = String.valueOf(char[] pas);
        use(password);
        password = "Pech gehabt";

klar das char array trotzdem mit 0ern überschreiben...
 
S

SlaterB

Gast
Obejktneuzuweisung bewirkt nicht, dass der GC das alte löscht
 
G

Gast2

Gast
Also so in etwas?Mal auf die schnelle =)

Java:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.security.*;

import javax.swing.JFrame;
import javax.swing.JPasswordField;

public class MD5Test extends JFrame {

    private JPasswordField field;

    public MD5Test() {
        super();
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        field = new JPasswordField(30);
        field.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                try {
                    printHash(field.getPassword().toString());
                } catch (NoSuchAlgorithmException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }

            }

        });
        add(field);
        setSize(100, 50);
        setLocationRelativeTo(null);
        setVisible(true);
    }

    private void printHash(String s) throws NoSuchAlgorithmException {
        MessageDigest md5 = MessageDigest.getInstance("MD5");
        md5.reset();

        md5.update(s.getBytes());
        byte[] result = md5.digest();

        /* Ausgabe */
        StringBuffer hexString = new StringBuffer();
        for (int i = 0; i < result.length; i++) {
            hexString.append(Integer.toHexString(0xFF & result[i]));
        }
        System.out.println(hexString.toString());
    }

    public static void main(String[] args) {
        new MD5Test();
    }

}
 
S

SlaterB

Gast
gib das mal in der Konsole aus:
field.getPassword().toString()

aber du wirst schon noch nen Weg finden, die chars aus dem char[] zu übertragen
oder sie in ein byte[] umzuwandeln für MessageDigest,
was da genau zu machen ist, kann ich nicht sagen, der Grundgedanke ist jedenfalls:
aus dem char[] einen Hashwert berechnen
 

Ebenius

Top Contributor
Umwandeln in byte[]-Array sollte so ganz schnuckelig gehen:
Java:
char[] cArray = null;
final CharBuffer cBuffer = CharBuffer.wrap(cArray);
final ByteBuffer bBuffer = Charset.forName("UTF-16").encode(cBuffer);
final byte[] bArray = bBuffer.array();
Arrays.fill(cArray, '\u0000');

// ... hier den Digest ermitteln

Arrays.fill(bArray, 0);
Ebenius
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
G Swing JPasswordField AWT, Swing, JavaFX & SWT 12
K Probleme beim JPasswordField AWT, Swing, JavaFX & SWT 11
OlafHD JPasswordField mit Button eingeben AWT, Swing, JavaFX & SWT 4
J JPasswordField kodiertes Passwort AWT, Swing, JavaFX & SWT 3
W JPasswordField AWT, Swing, JavaFX & SWT 5
C Swing JPasswordField wird nicht angezeigt AWT, Swing, JavaFX & SWT 27
VfL_Freak Swing Frage zu "new JPasswordField( 10 )" AWT, Swing, JavaFX & SWT 6
B Text im JPasswordField AWT, Swing, JavaFX & SWT 5
C Swing JPasswordField Password auslesen AWT, Swing, JavaFX & SWT 7
Y Swing JPasswordField Fehler AWT, Swing, JavaFX & SWT 14
M Swing jPasswordField getPassword() entschlüsseln AWT, Swing, JavaFX & SWT 9
W Swing JPasswordField "leeren" AWT, Swing, JavaFX & SWT 3
M JPasswordfield.getpassword() char[] nicht codiert auslesen? AWT, Swing, JavaFX & SWT 2
G JPopMenu und JPasswordField? AWT, Swing, JavaFX & SWT 7
K JPasswordField AWT, Swing, JavaFX & SWT 3
A Aus einem JPasswordField das Passwort auslesen AWT, Swing, JavaFX & SWT 3
Z Probleme mit JtextField und JPasswordField AWT, Swing, JavaFX & SWT 4
S JPasswordField warning : deprecation AWT, Swing, JavaFX & SWT 10
T Suche Methode zum anzeigen eines Textteils im JPasswordfield AWT, Swing, JavaFX & SWT 2
M JPasswordField AWT, Swing, JavaFX & SWT 7
F Eingabe in JPasswordField auf vier Zeichen beschränken AWT, Swing, JavaFX & SWT 3
W JPasswordField AWT, Swing, JavaFX & SWT 6

Ähnliche Java Themen


Oben