...
Any
...
time
...
an
...
application
...
stores
...
a
...
password
...
as
...
cleartext
...
(unencrypted
...
text
...
data),
...
its
...
value
...
is
...
potentially
...
exposed
...
in
...
a
...
variety
...
of
...
ways.
...
To
...
prevent
...
this
...
information
...
from
...
being
...
inadvertently
...
leaked,
...
this
...
exposure
...
must
...
be
...
limited.
...
While
...
a
...
program
...
will
...
receive
...
the
...
password
...
from
...
the
...
user
...
as
...
cleartext,
...
this
...
should
...
be
...
the
...
last
...
time
...
it
...
is
...
in
...
this
...
form.
...
Hash
...
functions
...
allow
...
programs
...
to
...
indirectly
...
compare
...
an
...
input
...
password
...
to
...
the
...
original,
...
without
...
storing
...
a
...
cleartext
...
or
...
decryptable
...
version
...
of
...
the
...
password.
...
This
...
approach
...
minimizes
...
the
...
exposure
...
of
...
the
...
password
...
without
...
presenting
...
any
...
practical
...
disadvantages.
...
Cryptographic
...
Hash
...
Functions
...
The
...
value
...
that
...
a
...
hash
...
function
...
outputs
...
is
...
called
...
the
...
hash
...
value
...
.
...
Another
...
term
...
for
...
hash
...
value
...
is
...
message
...
digest
...
.
...
Hash
...
functions
...
are
...
computationally
...
feasible
...
functions
...
whose
...
inverses
...
are
...
computationally
...
infeasible.
...
This
...
means
...
that
...
in
...
practice,
...
one
...
can
...
encode
...
a
...
password
...
to
...
a
...
hash
...
value,
...
while
...
they
...
are
...
also
...
unable
...
to
...
decode
...
it.
...
The
...
equality
...
of
...
the
...
passwords
...
can
...
be
...
tested
...
through
...
the
...
equality
...
of
...
their
...
hash
...
values.
...
Java's
...
MessageDigest
...
class
...
provides
...
the
...
functionality
...
of
...
various
...
cryptographic
...
hash
...
functions.
...
Be
...
careful
...
not
...
to
...
use
...
any
...
defective
...
hash
...
functions,
...
such
...
as
...
MD5
...
.
...
How
...
do
...
I
...
go
...
about
...
learning
...
which
...
hash
...
functions
...
are
...
safe,
...
and
...
which
...
are
...
defective?
...
It
...
is
...
also
...
important
...
that
...
you
...
append
...
a
...
salt
...
to
...
the
...
password
...
you
...
are
...
hashing.
...
A
...
salt
...
is
...
a
...
randomly
...
generated
...
piece
...
of
...
data
...
that
...
is
...
stored
...
along
...
with
...
the
...
hash
...
value.
...
The
...
use
...
of
...
a
...
salt
...
helps
...
prevents
...
dictionary
...
attacks
...
against
...
the
...
hash
...
value,
...
provided
...
the
...
salt
...
is
...
long
...
enough
...
what
...
is
...
long
...
enough
...
.
...
Each
...
password
...
should
...
have
...
its
...
own
...
salt
...
associated
...
with
...
it.
...
If
...
a
...
single
...
salt
...
were
...
used
...
for
...
more
...
than
...
one
...
password,
...
two
...
users
...
would
...
be
...
able
...
to
...
see
...
if
...
their
...
passwords
...
are
...
the
...
same.
...
Noncompliant
...
Code
...
Example
...
This
...
noncompliant
...
code
...
example
...
encrypts
...
and
...
decrypts
...
the
...
password
...
stored
...
in
...
credentials.pw.
Code Block | ||
---|---|---|
| ||
}} {code:bgColor=#FFcccc} public final class Password { private void setPassword(byte[] pass) throws Exception { Â bytes[] encrypted = encrypt(pass); //arbitrary encryption scheme clearArray(pass); Â Â saveBytes(encrypted,"password.bin"); //encrypted password to password.bin } private boolean checkPassword(byte[] pass) throws Exception { boolean arrays_equal; byte[] encrypted = loadBytes("password.bin"); //load the encrypted password byte[] decrypted = decrypt(encrypted); arrays_equal = Arrays.equal(decrypted, pass); clearArray(decrypted); clearArray(pass); return arrays_equal; } private clearArray(byte[] a) { //set all of the elements in a to zero } } {code} An attacker could potentially decrypt this file to discover the password. This attacker could be someone knows or has figured out the encryption scheme being used by the program. h2. Noncompliant Code Example This noncompliant code examples implements the {{SHA-1}} hash function through the {{MessageDigest}} class to compare hash values instead of cleartext strings. {code:bgColor=#FFcccc} |
An attacker could potentially decrypt this file to discover the password. This attacker could be someone knows or has figured out the encryption scheme being used by the program.
Noncompliant Code Example
This noncompliant code examples implements the SHA-1
hash function through the MessageDigest
class to compare hash values instead of cleartext strings.
Code Block | ||
---|---|---|
| ||
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public final class Password {
private void setPassword(String pass) throws Exception {
byte[] salt = generateSalt(12);
MessageDigest sha_1 = MessageDigest.getInstance("SHA-1");
byte[] hashVal = sha_1.digest((pass+salt).getBytes()); //encode the string and salt
saveBytes(salt, "salt.bin");
saveBytes(hashVal,"password.bin"); //save the hash value to credentials.bin
}
private boolean checkPassword(String pass) throws Exception {
byte[] salt = loadBytes("salt.bin");
MessageDigest sha_1 = MessageDigest.getInstance("SHA-1");
byte[] hashVal1 = sha_1.digest((pass+salt).getBytes()); //encode the string and salt
byte[] hashVal2 = loadBytes("password.bin"); //load the hash value stored in password.bin
return Arrays.equals(hashVal1, hashVal2);
}
private byte[] generateSalt(int n) {
//Generate a random byte array of length n
}
}
{code}
|
Even
...
if
...
an
...
attacker
...
knows
...
that
...
the
...
program
...
stores
...
passwords
...
using
...
SHA-1
...
and
...
a
...
12
...
byte
...
salt,
...
they
...
will
...
be
...
unable
...
to
...
get
...
the
...
value
...
of
...
the
...
password
...
from
...
password.bin
...
and
...
salt.bin
...
.
...
While
...
this
...
fixes
...
the
...
decryption
...
problem
...
from
...
the
...
previous
...
noncompliant
...
code
...
example,
...
at
...
runtime
...
this
...
code
...
may
...
inadvertently
...
store
...
the
...
passwords
...
as
...
cleartext.
...
This
...
is
...
because
...
the
...
pass
...
arguments
...
may
...
not
...
be
...
cleared
...
from
...
memory
...
by
...
the
...
Java
...
garbage
...
collector.
...
See
...
...
...
...
...
...
...
...
for
...
more
...
information.
...
Compliant
...
Solution
...
This
...
compliant
...
solution
...
addresses
...
the
...
problems
...
from
...
the
...
previous
...
noncompliant
...
examples.
Code Block | ||||
---|---|---|---|---|
| =
| |||
} import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; public final class Password { private void setPassword(byte[] pass) throws Exception { byte[] salt = generateSalt(12); byte[] input = appendArrays(pass, salt); MessageDigest sha_1 = MessageDigest.getInstance("SHA-1"); byte[] hashVal = sha_1.digest(input); //encode the string and salt  clearArray(pass);  clearArray(input); saveBytes(salt, "salt.bin");  saveBytes(hashVal,"password.bin"); //save the hash value to credentials.pw } private boolean checkPassword(byte[] pass) throws Exception { byte[] salt = loadBytes("salt.bin"); byte[] input = appendArrays(pass, salt); MessageDigest sha_1 = MessageDigest.getInstance("SHA-1"); byte[] hashVal1 = sha_1.digest(input); //encode the string and salt clearArray(pass); clearArray(input); byte[] hashVal2 = loadBytes("credentials.pw"); //load the hash value stored in credentials.pw return Arrays.equals(hashVal1, hashVal2); } private byte[] generateSalt(int n) { //Generate a random byte array of length n } private byte[] appendArrays(byte[] a, byte[] b) { //Return a new array of a appended to b } private void clearArray(byte[] a) { //set all of the elements in a to zero } } {code} |
In
...
both
...
the
...
setPassword()
...
and
...
checkPassword()
...
methods,
...
the
...
cleartext
...
representation
...
of
...
the
...
password
...
is
...
erased
...
as
...
soon
...
as
...
it
...
is
...
converted
...
into
...
a
...
hash
...
value.
...
After
...
this
...
happens,
...
there
...
is
...
no
...
way
...
for
...
an
...
attacker
...
to
...
get
...
the
...
password
...
as
...
cleartext.
...
Exceptions
MSC18-EX0
...
Applications such as password managers may need to retrieve the original password in order to enter it into a third-party application. This is okay even though it violates the guideline. The difference here is that the password manager is accessed by a single user. The program will always have the user's permission to store their passwords in this way. Therefore, provided the user is competent, the program's operation will be safe.
Risk Assessment
Violations of this rule have to be manually detected because it is a consequence of the overall design of the password storing mechanism. It is pretty unlikely, since it will occur around once or twice in a program that uses passwords. As demonstrated above, almost all violations of this rule have a clear exploit associated with them.
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
MSC18-J | medium | likely | high | P6 | L2 |
Bibliography
Wiki Markup |
---|
\[[API 2006|AA. Bibliography#API 06]\] Class {{java.security.MessageDigest}} |
...
http://www.javapractices.com/topic/TopicAction.do?Id=216
...
Passwords
...
never
...
in
...
clear
...
text