I'm currently creating the login functionality of a java web application just using java and JDBC. What built in java libraries are there to make the authentication process easier. I am able to query my PostgreSQL database and retrieve user information such as their password and username but I do not want to store it in plain text.Any tips would be great and o yeah I'm not using spring, which I see there is plenty for.
Asked
Active
Viewed 264 times
2
-
1Are you in a JEE type environment? If so, which one (i.e. Tomcat, Wildfly, etc.)? – stdunbar Jan 13 '22 at 01:37
-
Is JEE an IDE? If so I am using Intellij. If its a framework of any sort, than no I am not. – Nooby1 Jan 13 '22 at 01:41
-
Are you asking something like authentication to servlets? your API endpoints? or are you just trying to make a login page? I got confused when you said you don't want to store the credentials in plain text so I thought now you're asking how to store your passwords. – crimson589 Jan 13 '22 at 01:43
-
No, [JEE](https://stackoverflow.com/questions/7295096/what-exactly-is-java-ee) (previously J2EE) is a set of libraries and specifications but it sounds like this is a standalone Java program. Some of the code you've written would be useful. – stdunbar Jan 13 '22 at 01:48
-
I am currently only making the backend, API endpoints. I am not familiar with servlets. Just using Java JDBC with Postgres and an API I am storing the password in a PostgreSQL Database and am using a small web framework for controller. Does this make sense? – Nooby1 Jan 13 '22 at 01:48
-
O Java 1.8 if that helps – Nooby1 Jan 13 '22 at 01:51
1 Answers
2
Generally, password matching is done by storing a one-way hash of the password, instead of storing the password itself as plain text. When someone tries to log in, your application generates a one-way hash of the password the user has entered, and checks whether it matches any of the hashes stored in the database.
Hashing is done with the MessageDigest class:
byte[] passwordBytes = password.getBytes(StandardCharsets.UTF_8);
byte[] passwordHash;
try {
passwordHash = MessageDigest.getInstance("SHA-256").dist(passwordBytes);
} catch (NoSuchAlgorithmException e) {
// It should be impossible to get here, since SHA-256 is
// a standard algorithm supported by all Java runtimes.
throw new RuntimeException(e);
}
The password column in your database should be defined as a binary type, like VARBINARY. Then you can store the bytes directly:
try (PreparedStatement statement =
connection.prepareStatement(
"INSERT INTO users (name, passwordhash) VALUES (?, ?)")) {
statement.setString(1, name);
statement.setBytes(2, passwordHash);
statement.executeUpdate();
}
You can check whether a login attempt matches in a similar manner:
try (PreparedStatement statement =
connection.prepareStatement(
"SELECT name, email, phone FROM users"
+ " WHERE name = ? AND passwordHash = ?")) {
statement.setString(1, enteredName);
statement.setBytes(2, enteredPasswordHash);
ResultSet results = statement.executeQuery();
if (!results.next()) {
throw new MyAppInvalidLoginException("No matching login found.");
}
String name = results.getString(1);
String email = results.getString(2);
String phone = results.getString(3);
}
I’m not a security expert, so I will leave it to people with expertise in that area to comment on whether SHA-256 is sufficiently secure for general needs.

VGR
- 40,506
- 4
- 48
- 63
-
***For the paranoid:*** To have no lingering password in the server's JVM memory, you can afterwards do `Array.fill(passwordHash, (byte)0);` and likewise use `char[]` for the password and the corresponding statement setters. – Joop Eggen Jan 13 '22 at 13:14