Create a Simple Login Web Application with Encrypted Password in Java
Last Updated :
01 Jun, 2022
Security is an important concept in any web application. We need to have the passwords stored in an encrypted way i.e. the passwords are not easily accessible by hackers or unauthorized users. Let's see a small demo application in this article using MySQL, Java, Servlet, and JSP technology.
Step by Step Implementation
Required MySQL Script
-- Here GEEKSFORGEEKS is the db name
create table GEEKSFORGEEKS.login_key (
keyValue varchar(255)
);
In this keyValue a random value has to be inserted. That value should be time inserted one and by using that we can play around with encryption and decryption. Code to have a random value insertion.
Java
public static final String AES = "AES";
// This method generates a random key and stores in
// login_key table In the full program, let us see whole
// connection details
private void oneTimeKeyGeneration()
{
try {
KeyGenerator keyGen = KeyGenerator.getInstance(AES);
keyGen.init(128);
SecretKey sk = keyGen.generateKey();
String key = byteArrayToHexString(sk.getEncoded());
System.out.println("key:" + key);
getAndStoreLoginKey(key);
}
catch (Exception ex) {
System.out.println(ex.getMessage());
}
}
private static String byteArrayToHexString(byte[] b)
{
StringBuffer sb = new StringBuffer(b.length * 2);
for (int i = 0; i < b.length; i++) {
int v = b[i] & 0xff;
if (v < 16) {
sb.append('0');
}
sb.append(Integer.toHexString(v));
}
return sb.toString().toUpperCase();
}
private void getAndStoreLoginKey(String key)
{
try {
Class.forName("com.mysql.cj.jdbc.Driver")
.newInstance();
// Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/geeksforgeeks?useSSL=false",
"root", "admin");
String sql
= "INSERT INTO login_key(keyValue) VALUES(?)";
PreparedStatement pst = conn.prepareStatement(sql);
pst.setString(1, key);
pst.executeUpdate();
}
catch (ClassNotFoundException ex) {
Logger
.getLogger(
EncryptAndStorePassword.class.getName())
.log(Level.SEVERE, null, ex);
}
catch (SQLException ex) {
System.out.println("Exception.." + ex.getMessage());
}
catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
As the random key is inserted, we may be getting values like below
Let us create the 'GEEKPORTALLOGIN' table and create 2 entries into it
CREATE TABLE GEEKSFORGEEKS.GEEKPORTALLOGIN (id INT NOT NULL,
loginName VARCHAR(20) default NULL,
password VARCHAR(45) default NULL,
PRIMARY KEY (id)
);
INSERT INTO GEEKSFORGEEKS.GEEKPORTALLOGIN VALUES(1,'GEEKA','GEEKA');
INSERT INTO GEEKSFORGEEKS.GEEKPORTALLOGIN VALUES(2,'GEEKB','GEEKB');
Using the key mentioned in "Key Image", the password can be encrypted by using the code below
Java
import java.security.NoSuchAlgorithmException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
public class EncryptAndStorePassword {
Connection conn = null;
public static final String AES = "AES";
String key = null;
public Connection getConnection()
{
try {
Class.forName("com.mysql.cj.jdbc.Driver")
.newInstance();
conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/geeksforgeeks?useSSL=false",
"root", "admin");
Statement st;
st = conn.createStatement();
ResultSet rs = st.executeQuery(
"select * from login_key");
// Get the key value from login_key
while (rs.next()) {
key = rs.getString("keyValue");
}
System.out.println("key=" + key);
}
catch (ClassNotFoundException ex) {
Logger
.getLogger(
EncryptAndStorePassword.class.getName())
.log(Level.SEVERE, null, ex);
}
catch (SQLException ex) {
System.out.println("Exception.."
+ ex.getMessage());
}
catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return conn;
}
private void closeConnection()
{
try {
conn.close();
conn = null;
}
catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// Utility method taking input as byte array and giving
// String as output
private static String byteArrayToHexString(byte[] b)
{
StringBuffer sb = new StringBuffer(b.length * 2);
for (int i = 0; i < b.length; i++) {
int v = b[i] & 0xff;
if (v < 16) {
sb.append('0');
}
sb.append(Integer.toHexString(v));
}
return sb.toString().toUpperCase();
}
// Utility method taking input as String and giving byte
// array as output
private static byte[] hexStringToByteArray(String s)
{
byte[] b = new byte[s.length() / 2];
for (int i = 0; i < b.length; i++) {
int index = i * 2;
int v = Integer.parseInt(
s.substring(index, index + 2), 16);
b[i] = (byte)v;
}
return b;
}
public EncryptAndStorePassword(String tableName)
{
getConnection();
// oneTimeKeyGeneration();//This has to be done only
// one time. Based on the key, password are getting
// encrypted and using this key only decrypt will
// happen and check for username and password
// combination
doSelectAndUpdate(tableName);
closeConnection();
}
private void doSelectAndUpdate(String tableName)
{
doSelect("GEEKPORTALLOGIN");
// Passing table name will be a good approach as it
// can do for any table. Just change table name alone
}
// This is the one time approach of storing key value in
// login_key
private void getAndStoreLoginKey(String key)
{
try {
String sql
= "INSERT INTO login_key(keyValue) VALUES(?)";
PreparedStatement pst
= conn.prepareStatement(sql);
pst.setString(1, key);
pst.executeUpdate();
}
catch (SQLException ex) {
System.out.println("SQLException.."
+ ex.getMessage());
}
}
// This is the one time approach of storing key value in
// login_key
private void oneTimeKeyGeneration()
{
try {
KeyGenerator keyGen
= KeyGenerator.getInstance(AES);
keyGen.init(128);
SecretKey sk = keyGen.generateKey();
String key
= byteArrayToHexString(sk.getEncoded());
System.out.println("key:" + key);
getAndStoreLoginKey(key);
}
catch (Exception ex) {
System.out.println(ex.getMessage());
}
}
// Get the details from GEEKPORTALLOGIN and update
// encrypted password
private void doSelect(String tableName)
{
Statement st;
String query = null, password = null,
userName = null;
query = "SELECT * FROM GEEKPORTALLOGIN";
try {
st = conn.createStatement();
ResultSet rs = st.executeQuery(query);
while (rs.next()) {
userName = rs.getString("loginName");
password = rs.getString("password");
byte[] passwordByte
= hexStringToByteArray(key);
System.out.println("keyValue.." + key);
SecretKeySpec sks = new SecretKeySpec(
passwordByte,
EncryptAndStorePassword.AES);
Cipher cipher = Cipher.getInstance(
EncryptAndStorePassword.AES);
cipher.init(Cipher.ENCRYPT_MODE, sks,
cipher.getParameters());
byte[] encrypted
= cipher.doFinal(password.getBytes());
String encryptedpwd
= byteArrayToHexString(encrypted);
// System.out.println("****************
// Encrypted Password ****************");
System.out.println(encryptedpwd);
// System.out.println("****************
// Encrypted Password ****************");
doUpdate(encryptedpwd, userName,
"GEEKPORTALLOGIN");
}
}
catch (SQLException ex) {
Logger
.getLogger(
EncryptAndStorePassword.class.getName())
.log(Level.SEVERE, null, ex);
}
catch (Exception ex) {
System.err.println(ex.getMessage());
}
}
// Updating encrypted password for the users
private void doUpdate(String password, String userName,
String tableName)
{
System.out.print("\n[Performing UPDATE] ... ");
try {
Statement st = conn.createStatement();
String sqlUpdate = null;
sqlUpdate = "UPDATE GEEKPORTALLOGIN "
+ "SET password = ? "
+ "WHERE loginName = ?";
PreparedStatement pstmt
= conn.prepareStatement(sqlUpdate);
pstmt.setString(1, password);
pstmt.setString(2, userName);
int rowAffected = pstmt.executeUpdate();
System.out.println(String.format(
"Row affected %d", rowAffected));
}
catch (SQLException ex) {
System.err.println(ex.getMessage());
}
}
public static void main(String args[])
throws NoSuchAlgorithmException
{
EncryptAndStorePassword encryptAndStorePassword
= null;
// Open a connection
try {
encryptAndStorePassword
= new EncryptAndStorePassword(
"GEEKPORTALLOGIN");
}
finally {
// close connections
// nullify variables etc.,
}
}
}
On execution of this plain java program, we can see the output as
At the same time, we can able to see MySQL output as
Now let us have a small web application that has a simple login form. There we will be providing credentials as GEEKA/GEEKA only. But still, the application can able to Login.
Let us see the bean, DAO, and servlet files now
LoginBean.java
Java
import java.io.Serializable;
public class LoginBean implements Serializable {
private static final long serialVersionUID = 1L;
// equivalent to GEEKPORTALLOGIN, specifiers are given
// and corresponding getter and setter
private String loginName;
private String password;
public String getLoginName() { return loginName; }
public void setLoginName(String loginName)
{
this.loginName = loginName;
}
public String getPassword() { return password; }
public void setPassword(String password)
{
this.password = password;
}
}
LoginDao.java
Java
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
import net.gfg.login.bean.LoginBean;
public class LoginDao {
public boolean validate(LoginBean loginBean)
throws ClassNotFoundException
{
boolean status = false;
Class.forName("com.mysql.jdbc.Driver");
try {
Connection connection = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/geeksforgeeks?useSSL=false",
"root", "admin");
String key = null;
Statement st;
st = connection.createStatement();
ResultSet rs = st.executeQuery(
"select * from login_key");
while (rs.next()) {
key = rs.getString("keyValue");
}
System.out.println(
"key.." + key); // This value is a one time
// generated one
// As encryption occurred using this key,
// decryption also should occur with this key.
// Step 2:Create a statement using connection
// object
PreparedStatement preparedStatement
= connection.prepareStatement(
"select * from GEEKPORTALLOGIN where loginName = ?");
preparedStatement.setString(
1, loginBean.getLoginName());
// For the logged in username, get the password
rs = preparedStatement.executeQuery();
String encryptedPassword = null;
while (rs.next()) {
// As it is taken from db, we will get
// encrypted one only
encryptedPassword
= rs.getString("password");
}
// Here we need to get the decrypted password
String decrypptedPassword
= decryptPassword(key, encryptedPassword);
// check the decrypted password and the user
// entered password are same. it should match and
// then we can say login is success
if (decrypptedPassword != null
&& decrypptedPassword.equalsIgnoreCase(
loginBean.getPassword())) {
status = true;
}
}
catch (SQLException e) {
// process sql exception
displaySQLException(e);
}
return status;
}
public byte[] hexStringToByteArray(String s)
{
byte[] b = new byte[s.length() / 2];
for (int i = 0; i < b.length; i++) {
int index = i * 2;
int v = Integer.parseInt(
s.substring(index, index + 2), 16);
b[i] = (byte)v;
}
return b;
}
public String decryptPassword(String key,
String encryptedPassword)
{
String decryptedPassword = null;
try {
byte[] bytekey = hexStringToByteArray(key);
SecretKeySpec sks
= new SecretKeySpec(bytekey, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, sks);
byte[] decrypted = cipher.doFinal(
hexStringToByteArray(encryptedPassword));
decryptedPassword = new String(decrypted);
}
catch (NoSuchAlgorithmException ex) {
System.out.println(ex.getMessage());
}
catch (NoSuchPaddingException ex) {
System.out.println(ex.getMessage());
}
catch (InvalidKeyException ex) {
System.out.println(ex.getMessage());
}
catch (IllegalBlockSizeException ex) {
System.out.println(ex.getMessage());
}
catch (BadPaddingException ex) {
System.out.println(ex.getMessage());
}
return decryptedPassword;
}
private void displaySQLException(SQLException ex)
{
// for (Throwable e : ex) {
if (ex instanceof SQLException) {
ex.printStackTrace(System.err);
System.err.println(
"SQLState: "
+ ((SQLException)ex).getSQLState());
System.err.println(
"Error Code: "
+ ((SQLException)ex).getErrorCode());
System.err.println("Message: "
+ ex.getMessage());
Throwable t = ex.getCause();
while (t != null) {
System.out.println("Cause: " + t);
t = t.getCause();
}
}
//}
}
}
LoginServlet.java
Java
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.gfg.login.bean.LoginBean;
import net.gfg.login.database.LoginDao;
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private LoginDao loginDao;
public void init() { loginDao = new LoginDao(); }
protected void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException
{
String loginName
= request.getParameter("loginName");
String password = request.getParameter("password");
LoginBean loginBean = new LoginBean();
loginBean.setLoginName(loginName);
// Here we need to write the decryption logic
// GEEKSFORGEEKS.login_key should be the medium for
// encryption as well as decryption
loginBean.setPassword(password);
// Inside validate, user entered password should
// match with the password available in db. db
// password is in encrypted mode. It has to undergo
// decryption techniques and we should get the
// password back
try {
if (loginDao.validate(loginBean)) {
response.sendRedirect("loginsuccess.jsp");
}
else {
// HttpSession session =
// request.getSession();
}
}
catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
Login.jsp
Java
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Login Form by using Encrypted password</title>
</head>
<body>
<div align="center">
<h1>Login Form</h1>
<form action="<%=request.getContextPath()%>/login" method="post">
<table style="with: 100%">
<tr>
<td>Login</td>
<td><input type="text" name="loginName" /></td>
</tr>
<tr>
<td>Password</td>
<td><input type="password" name="password" /></td>
</tr>
</table>
<input type="submit" value="Submit" />
</form>
</div>
</body>
</html>
loginsuccess.jsp
Java
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%@page import="net.gfg.login.database.*"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<div align="center">
<h1>You have logged in successfully</h1>
</div>
</body>
</html>
Program Execution
Need to give GEEKA/GEEKA. As we are following the decryption technique inside the project, the user can able to login successfully.
We can able to successfully log in
Inside the validate method,
- For the given login, the password (encrypted one) is fetched from DB
- Decryption is happening for the retrieved password
- Then the user-entered password is matched with the decrypted password and if they match, the login is successful.
- The main important thing is the login_key.keyValue should be generated one Time only and with that, any kind of password can be encrypted and decrypted easily.
Similar Reads
Web Container and Web Application Project Setup in Java
Web container is a web server component that interacts with the Java Servlets. This processes the requests to the requested servlet while checking the required access rights of the URL. Web containerThe functioning is as follows: The web client requests a URL to the web server.The web container in t
2 min read
Create a Form with Show/Hide Password in Tailwind CSS
Show/Hide Password visibility is the feature in web applications through which users can view the entered password with dynamic behavior by toggling through the show/hide icon. This increases the user experience in a visually appealing way. The user can easily maintain security while filling out for
2 min read
Best Practices for Secure Coding in Web Applications
Web applications are essential for corporations to deliver digital offerings, and they have got grow to be increasingly important in recent years as increasingly human beings get proper access to offerings online. However, with the upward push of cyber-assaults and data breaches, itâs vital to put i
6 min read
How to encrypt passwords in a Spring Boot project using Jasypt
In this article, we will learn how to encrypt data in Spring Boot application config files like application.properties or application.yml. Inside those files, we can encrypt username, password, etc. You often come across developing projects where you have to connect to databases like MongoDB, etc, a
4 min read
Console readPassword() method in Java with Examples
The readPassword() method of Console class in Java is of two types: 1. The readPassword() method of Console class in Java is used to read a password or passphrase from the console with disabled echoing. Syntax: public char[] readPassword() Parameters: This method does not accept any parameter. Retur
4 min read
If we delete cookies of a site, we can still logged in without logging again
The facebook is coded in PHP and PHP was launched in 1994. But in PHP, there is a disadvantage i.e if we disable cookies (say in Facebook) the Facebook server will forget the person who has logged in previously and it will take to me that page when that application was launched for the first time. B
6 min read
Build a Password Generator App with HTML CSS and JavaScript
In this article, we will build a password generator application using HTML, CSS, and JavaScript. This application will generate strong and secure passwords based on user preferences, such as password length and character types. It aims to provide a convenient tool for users to generate random passwo
3 min read
KeyStore getEntry() method in Java with Examples
The getEntry() method of java.security.KeyStore class is used to get the keystore entry for this instance with the help of the specified alias and the protection parameter. Syntax: public final KeyStore.Entry getEntry(String alias, KeyStore.ProtectionParameter protParam) throws NoSuchAlgorithmExcept
3 min read
Spring Security - Secure Your Web Application
Spring Security is a powerful and highly customizable security framework that provides authentication, authorization, and other security features for Spring-based applications. It is a widely used open-source project that helps developers to secure their web applications by implementing security pol
7 min read
Creating First Servlet Application using NetBeans IDE
Servlets are the Java programs that run on the Java-enabled web server or application server. They are used to handle the request obtained from the webserver, process the request, produce the response, then send a response back to the webserver. NetBeans is an integrated development environment (IDE
2 min read