CoreJava Java

Auto-Generate a Secure Password in Java – Plain Java, Servlet, and Struts2

Auto-Generate a Secure Password in Java – Plain Java, Servlet, and Struts2

Generating a random password is a common requirement for user registration, password reset, and account creation flows. This tutorial shows three implementations: a plain Java utility class, a Java Servlet endpoint, and how to call it from a Struts2 action.

Approach: Build a Utility Class

The safest approach is to create a reusable PasswordGenerator utility that uses SecureRandom (cryptographically strong) instead of java.util.Random. A good password mixes uppercase letters, lowercase letters, digits, and special characters.

PasswordGenerator.java – Plain Java Utility

package com.java9r.util;

import java.security.SecureRandom;

public class PasswordGenerator {

    private static final String UPPERCASE  = "ABCDEFGHJKLMNPQRSTUVWXYZ";
    private static final String LOWERCASE  = "abcdefghjkmnpqrstuvwxyz";
    private static final String DIGITS     = "23456789";
    private static final String SPECIALS   = "@#$%!&*";

    // Combined pool — note: ambiguous chars (0, O, l, 1, I) excluded
    private static final String ALL_CHARS  = UPPERCASE + LOWERCASE + DIGITS + SPECIALS;

    private static final SecureRandom RANDOM = new SecureRandom();

    /**
     * Generate a password of the specified length.
     * Guarantees at least one character from each category.
     */
    public static String generate(int length) {
        if (length < 8) throw new IllegalArgumentException("Minimum length is 8");

        char[] password = new char[length];

        // Ensure at least one from each category
        password[0] = UPPERCASE.charAt(RANDOM.nextInt(UPPERCASE.length()));
        password[1] = LOWERCASE.charAt(RANDOM.nextInt(LOWERCASE.length()));
        password[2] = DIGITS.charAt(RANDOM.nextInt(DIGITS.length()));
        password[3] = SPECIALS.charAt(RANDOM.nextInt(SPECIALS.length()));

        // Fill the rest from the combined pool
        for (int i = 4; i < length; i++) {
            password[i] = ALL_CHARS.charAt(RANDOM.nextInt(ALL_CHARS.length()));
        }

        // Shuffle to avoid predictable positions
        for (int i = length - 1; i > 0; i--) {
            int j = RANDOM.nextInt(i + 1);
            char tmp = password[i];
            password[i] = password[j];
            password[j] = tmp;
        }

        return new String(password);
    }

    public static void main(String[] args) {
        System.out.println("Generated Passwords:");
        for (int i = 1; i <= 5; i++) {
            System.out.println(i + ": " + generate(12));
        }
    }
}

Output

Generated Passwords:
1: sK7@mRb!nY3D
2: G9!vTz#mCp5W
3: Lq&8Hn2$rXkM
4: Yw5@bN!tDm3Z
5: Px7#KvT&nR2s

Java Servlet – Generate Password via HTTP

package com.java9r.servlet;

import com.java9r.util.PasswordGenerator;
import javax.servlet.http.*;
import javax.servlet.*;
import java.io.IOException;
import java.io.PrintWriter;

public class PasswordServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        String lengthParam = request.getParameter("length");
        int length = 12;   // default length
        if (lengthParam != null) {
            try {
                length = Integer.parseInt(lengthParam);
            } catch (NumberFormatException ignored) {}
        }

        String password = PasswordGenerator.generate(length);

        response.setContentType("application/json");
        response.setCharacterEncoding("UTF-8");

        PrintWriter out = response.getWriter();
        out.print("{\"password\": \"" + password + "\", \"length\": " + length + "}");
        out.flush();
    }
}

web.xml (Servlet mapping)

<servlet>
    <servlet-name>PasswordServlet</servlet-name>
    <servlet-class>com.java9r.servlet.PasswordServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>PasswordServlet</servlet-name>
    <url-pattern>/generatePassword</url-pattern>
</servlet-mapping>

Usage

GET /generatePassword           → 12-character password
GET /generatePassword?length=16 → 16-character password

Struts2 Action – Generate Password

package com.java9r.action;

import com.java9r.util.PasswordGenerator;
import com.opensymphony.xwork2.ActionSupport;

public class PasswordAction extends ActionSupport {

    private String generatedPassword;
    private int    length = 12;

    public String execute() {
        generatedPassword = PasswordGenerator.generate(length);
        return SUCCESS;
    }

    public String getGeneratedPassword() { return generatedPassword; }
    public int    getLength()            { return length; }
    public void   setLength(int length)  { this.length = length; }
}

struts.xml

<action name="generatePassword"
        class="com.java9r.action.PasswordAction">
    <result name="success">/WEB-INF/jsp/password.jsp</result>
</action>

password.jsp

<%@ page contentType="text/html;charset=UTF-8" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head><title>Generated Password</title></head>
<body>
  <h2>Generated Password</h2>
  <p><strong><s:property value="generatedPassword"/></strong></p>
  <form action="generatePassword" method="get">
    Length: <input type="number" name="length" value="12" min="8" max="32">
    <input type="submit" value="Generate New">
  </form>
</body>
</html>

SecureRandom vs Random – Why It Matters

Aspect java.util.Random java.security.SecureRandom
Source of randomness Pseudo-random (seed-based) OS-level entropy (cryptographically strong)
Predictable? Yes, if seed is known No
Performance Faster Slightly slower (acceptable for passwords)
Use for passwords? No — security risk Yes — always use for security tokens

Summary

The key to a good password generator is: use SecureRandom (not Random), exclude visually ambiguous characters (0, O, l, 1), guarantee at least one character from each required category (uppercase, lowercase, digit, special), and shuffle the result so the guaranteed characters are not always at fixed positions. Wrap this in a utility class so it can be called from plain Java, a Servlet, or a Struts2/Spring action without duplication.

Topics: CoreJava Java
← Newer Post Older Post →

Comments

https://www.blogger.com/comment/frame/6690124484600543990?po=4073814005603100876&hl=en&saa=85391&origin=https://www.java9r.com