Generate CAPTCHA Images with Java
A basic image CAPTCHA generates a random challenge, stores its expected value on the server, draws the characters into an image, and returns the image with no-cache headers.
Use SecureRandom rather than predictable Random for challenge generation. Render with BufferedImage and Graphics2D, add moderate distortion or noise, and write the response with ImageIO.
The expected answer should be stored in a short-lived server-side session or challenge record, never trusted from a hidden form field. Compare answers in constant, normalized form where practical, expire them quickly, invalidate after success, and rate-limit attempts.
response.setContentType("image/png");
response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
ImageIO.write(image, "png", response.getOutputStream());
A homemade visual CAPTCHA is not a strong bot defense by itself and may create accessibility problems. For higher-risk systems, combine rate limits, abuse detection, device and session signals, accessible alternatives, and a maintained challenge service.