首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 驗證碼生成核心流程與實現方案:圖形驗證碼、滑塊驗證、行為分析

     編輯:Java 相關知識

Java 驗證碼體系全景:從圖形干擾到無感驗證的演進之路

驗證碼是區分人機的第一道防線。本文系統梳理圖形驗證碼生成流程、滑塊拼圖驗證邏輯、行為分析無感驗證架構,提供生產級代碼骨架與安全加固建議。

一、圖形驗證碼生成標準流程

1. 參數初始化
   - 畫布尺寸 (寬×高),字符集、字體、顏色範圍
   - 干擾元素:干擾線、噪點、幹擾圓、扭曲變換

2. 圖像緩衝創建
   BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
   Graphics2D g = image.createGraphics();

3. 背景填充
   g.setColor(randomLightColor());
   g.fillRect(0, 0, width, height);

4. 干擾線繪製 (5-10 條)
   for (int i = 0; i < lineCount; i++) {
       g.setColor(randomColor());
       g.drawLine(randomX(), randomY(), randomX(), randomY());
   }

5. 驗證碼字符繪製 (4-6 位)
   StringBuilder code = new StringBuilder();
   for (int i = 0; i < length; i++) {
       char c = randomChar();
       code.append(c);
       g.setFont(randomFont());
       g.setColor(randomDarkColor());
       g.rotate(randomAngle(), x, y); // 字符級旋轉
       g.drawString(String.valueOf(c), x, y);
       g.rotate(-randomAngle(), x, y); // 恢復
       x += charWidth + gap;
   }

6. 干擾噪點 (可選)
   for (int i = 0; i < noiseCount; i++) {
       g.setColor(randomColor());
       g.drawRect(randomX(), randomY(), 1, 1);
   }

7. 釋放資源 & 輸出
   g.dispose();
   ImageIO.write(image, "jpeg", outputStream); // 或 PNG

8. 會話存儲
   session.setAttribute("captcha_code", code.toString().toLowerCase());
   session.setAttribute("captcha_time", System.currentTimeMillis());

二、核心工具類實現

public class CaptchaUtil {
    private static final String CHARS = "23456789ABCDEFGHJKLMNPQRSTUVWXYZ"; // 排除易混淆字符
    private static final Color[] FONT_COLORS = {Color.BLACK, Color.BLUE, Color.RED, Color.GREEN};
    private static final Font[] FONTS = {
        new Font("Arial", Font.BOLD, 24),
        new Font("Courier New", Font.BOLD | Font.ITALIC, 26),
        new Font("Verdana", Font.BOLD, 22)
    };
    
    public static BufferedImage generate(StringBuilder codeHolder, int width, int height, int length) {
        // 實現上述流程...
    }
    
    private static char randomChar() { return CHARS.charAt(random.nextInt(CHARS.length())); }
    private static Color randomColor() { return new Color(random.nextInt(200), random.nextInt(200), random.nextInt(200)); }
    private static Color randomLightColor() { return new Color(200 + random.nextInt(55), 200 + random.nextInt(55), 200 + random.nextInt(55)); }
    private static Color randomDarkColor() { return new Color(random.nextInt(100), random.nextInt(100), random.nextInt(100)); }
    private static Font randomFont() { return FONTS[random.nextInt(FONTS.length)]; }
    private static double randomAngle() { return (random.nextDouble() - 0.5) * 0.6; } // ±0.3 rad
}

三、Spring MVC / Servlet 整合控制器

@Controller
public class CaptchaController {
    @GetMapping("/captcha/image")
    public void imageCaptcha(HttpServletResponse response, HttpSession session) throws IOException {
        response.setHeader("Cache-Control", "no-store, no-cache");
        response.setContentType("image/jpeg");
        
        StringBuilder code = new StringBuilder();
        BufferedImage image = CaptchaUtil.generate(code, 120, 40, 4);
        
        session.setAttribute("captcha_code", code.toString().toLowerCase());
        session.setAttribute("captcha_time", System.currentTimeMillis());
        
        ImageIO.write(image, "JPEG", response.getOutputStream());
    }
    
    @PostMapping("/captcha/verify")
    @ResponseBody
    public Result verify(@RequestParam String input, HttpSession session) {
        String code = (String) session.getAttribute("captcha_code");
        Long time = (Long) session.getAttribute("captcha_time");
        
        if (code == null || time == null) return Result.fail("驗證碼已過期");
        if (System.currentTimeMillis() - time > 5 * 60 * 1000) return Result.fail("驗證碼已過期");
        if (!code.equals(input.toLowerCase())) return Result.fail("驗證碼錯誤");
        
        session.removeAttribute("captcha_code"); // 一次性使用
        return Result.ok();
    }
}

四、滑塊拼圖驗證 (前後端協作)

階段後端職責前端職責
初始化1. 隨機選取背景圖
2. 生成隨機缺口座標 (x, y)
3. 裁剪滑塊圖片
4. 返回 {bgUrl, sliceUrl, token, 期望x座標(加密)}
1. 請求初始化數據
2. 渲染背景圖 + 滑塊
3. 綁定拖拽事件
驗證1. 解密期望座標
2. 計算誤差 |用戶x - 期望x|
3. 判定閾值 (通常 ±5px)
4. 記錄軌跡數據供風控分析
1. 收集滑動軌跡 (x, y, t)
2. 提交 {token, 用戶x, 軌跡數據}

五、行為分析無感驗證架構

// 風控引擎輸入特徵
class RiskFeatures {
    // 設備指紋
    String deviceId, userAgent, screenResolution, timezone, language;
    // 行為序列
    List events; // click, scroll, mousemove, keydown, touch
    // 環境上下文
    String ip, geoLocation, isp, proxyScore;
    // 業務上下文
    String actionType, referrer, sessionId;
}

// 規則引擎 + 機器學習模型
class RiskEngine {
    public RiskResult evaluate(RiskFeatures features) {
        // 1. 規則檢查 (白名單、黑名單、頻率限制)
        // 2. 模型推理 (XGBoost/LightGBM/神經網絡) -> 風險分 0-100
        // 3. 決策邏輯
        if (score < 20) return RiskResult.PASS;           // 直通
        if (score < 60) return RiskResult.CAPTCHA;        // 彈出驗證碼
        if (score < 90) return RiskResult.SLIDER;         // 滑塊驗證
        return RiskResult.BLOCK;                          // 直接攔截
    }
}

六、安全加固清單

  • 防暴力破解:IP + 設備雙維度限流 (Redis 計數器、滑動窗口)
  • 防重放攻擊:驗證碼一次性失效、Token 單次使用、時間戳防重放
  • 防機器識別:字符扭曲、字體隨機、干擾線密度、點擊軌跡分析 (人類抖動 vs 線性)
  • 無障礙支援:提供音頻驗證碼、語音播報、簡單問答備選方案
  • 監控告警:驗證通過率、人均嘗試次數、滑塊平均耗時、攔截率趨勢

七、成熟方案推薦

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
類型開源/商業特點
kaptcha / simple-captcha開源輕量圖形驗證碼,易整合
Geetest (極驗)商業滑塊+行為分析,免部署 SDK
hCaptcha / reCAPTCHA v3商業無感行為分析,全球威脅情報
Tencent Cloud Captcha商業國內訪問快、合規、多模式