entering Password (a String) without leaving in-memory traces

O

otf

Hi *,

I remember I once read an article at java.sun.com about how you could
implement certain functionality extending JTextPassword that would not
leave in-memory traces of the characters entered

I read about it, I think at the technical articles and tips forum, but at
that time I didn't have the time to dive into it. Now, I can not find
it :-(

Does anyone here have these ideas fresh and remember/know what the links
are?

Thanks
otf
 
C

Chris Smith

otf said:
I remember I once read an article at java.sun.com about how you could
implement certain functionality extending JTextPassword that would not
leave in-memory traces of the characters entered

I read about it, I think at the technical articles and tips forum, but at
that time I didn't have the time to dive into it. Now, I can not find
it :-(

The class is JPasswordField. Create it without an initial value, and
call getPassword instead of getText. Zero out the char[] after you're
done with the value. You have to be careful not to create your own
String objects out of the result, though.

--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
R

Roedy Green

Does anyone here have these ideas fresh and remember/know what the links
are?

basically the idea is you never let the password exists as a string,
only as a char[]. That way you can zap it.
 
C

Chris Uppal

Chris said:
The class is JPasswordField. Create it without an initial value, and
call getPassword instead of getText. Zero out the char[] after you're
done with the value. You have to be careful not to create your own
String objects out of the result, though.

Even with those cautions, I doubt whether JPasswordField counts as "not leaving
in-memory traces", not when there's a copying garbage collector in the system.

AFAIK, it's not actually possible to do on all OSes -- at least the crypto
people seem fairly sure that there's no defined way of doing it (that actually
/works/) on Windows.

Not to say that JPasswordField, if used as Chris describes, isn't a reasonable
solution for a given application.

Actually, looking at the code, I'm not too impressed. In terms of sofware
engineering, it inherits from JTextField and (therefore) uses Document --
complex classes that have no security responsibilities themeselves and which
are therefore fragile if used in a secure context. In terms of functionality,
there is no need to keep the password text "in plain" in memory at all, and
there should be an API for retrieving it without assembling it into a String or
char[]. You can't get security against an attacker who is able to review /all/
the contents of memory, but you can certainly -- and quite easily -- make the
job of a would-be attacker using a partial memory trace (say from the "swap"
file), and lacking the resources of a major governement, much harder or even
(perhaps) impossible. Of course, for that level of protection to make sense,
there must also be a way to /use/ the password which doesn't require assembling
it into plaintext in memory, and (afaik) such APIs don't commonly exist, and
for some purposes may not even be possible.

-- chris
 
C

Chris Smith

Chris Uppal said:
Even with those cautions, I doubt whether JPasswordField counts as "not leaving
in-memory traces", not when there's a copying garbage collector in the system.

Indeed. On the other hand (but for the problems below) it would at
least be possible to minimize the probability. So long as the object
were not kept for long, it would be unlikely to copied too much, and the
younger generations would be likely to be overwritten quickly with newly
allocated objects.

Problems with copies due to virtual memory in the operating system are
equally difficult and far less transient, but are also even less likely
to happen so long as the data is disposed of quickly.
Actually, looking at the code, I'm not too impressed.

Looking at the code, I'm not too impressed, either. I had assumed that
JPasswordField used a custom implementation of Document that prevents
discarded copies of data, and that getPassword() returned the actual
underlying char[] used by the Document implementation. It turns out
that's not the case; there is no special-purpose document, and
getPassword() just makes another copy of the text. This makes
getPassword basically useless; may as well use getText instead.

Except that getText is deprecated. That, then, is the kind of arrogance
in API design that gets my hackles up from Sun occasionally. Even if
JPasswordField and getPassword() were implemented properly, this kind of
trick would be unnecessary in 99% of cases where JPasswordField is used.
Instead of allowing for that, someone from Sun decides to demonstrate
horrible OO design (deprecating a method in a subclass that is public
and definitely not deprecated in the superclass) and take away a tool
that could prevent a conversion step in the normal case of an
application.

--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
R

Roedy Green

Even with those cautions, I doubt whether JPasswordField counts as "not leaving
in-memory traces", not when there's a copying garbage collector in the system.

here is the code for JPassword.getPassword. You are supposed to clear
the returned array after you are finished with it. It seems to me
there are still TWO copies of the password lying around in RAM after
this is done: the uncollected Segment and the Document.
You could wipe the document with setText("ZZZZZZZZZZZZZZZZZZZZZZZZ");
For better security Sun should have zapped the segment after copying
it to the final array.

/**
* Returns the text contained in this <code>TextComponent</code>.
* If the underlying document is <code>null</code>, will give a
* <code>NullPointerException</code>. For stronger
* security, it is recommended that the returned character array
be
* cleared after use by setting each character to zero.
*
* @return the text
*/
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;
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,900
Latest member
Nell636132

Latest Threads

Top