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

Java 後端 MD5 加密實戰:密碼重置與安全存儲最佳實踐

     編輯:Java 相關知識

業務場景:忘記密碼重置流程

用戶忘記密碼 → 後端生成 6 位隨機臨時密碼 → 經由即時通/簡訊/微信發送 → 同步更新資料庫密碼(存儲 MD5 密文) → 用戶登入後強制修改密碼。

核心安全要求:

  • 明文密碼絕不落庫、不傳輸、不日誌
  • 隨機密碼生成於後端,前端不可預測
  • 傳輸過程加密(HTTPS)、儲存採用單向雜湊 + Salt

MD5 工具類實現(32 位十六進制)


public final class Md5Utils {
    private Md5Utils() {} // 工具類禁止實例化

    /**
     * 計算字串的 MD5 雜湊值(32 位小寫十六進制)
     * @param input 待加密明文
     * @return 32 位十六進制字串,輸入為 null 返回空串
     */
    public static String encode(String input) {
        if (input == null) return "";
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] digest = md.digest(input.getBytes(StandardCharsets.UTF_8));

            // 位元組陣列轉十六進制字串
            StringBuilder sb = new StringBuilder(32);
            for (byte b : digest) {
                int v = b & 0xFF; // 無符號位元組值
                if (v < 0x10) sb.append('0'); // 高位補零
                sb.append(Integer.toHexString(v));
            }
            return sb.toString();
        } catch (NoSuchAlgorithmException e) {
            throw new IllegalStateException("JVM 缺少 MD5 實現", e);
        }
    }

    /**
     * 驗證明文與雜湊值是否匹配(防時序攻擊用 MessageDigest.isEqual)
     */
    public static boolean matches(String raw, String hash) {
        if (raw == null || hash == null) return false;
        String calculated = encode(raw);
        return MessageDigest.isEqual(calculated.getBytes(StandardCharsets.UTF_8),
                                     hash.getBytes(StandardCharsets.UTF_8));
    }
}

控制器層整合範例


@RestController
@RequestMapping("/api/auth")
public class AuthController {
    @Autowired private UserService userService;
    @Autowired private MessageService messageService;

    @PostMapping("/reset-password")
    public Result<Void> resetPassword(@RequestParam Long userId) {
        // 1. 生成 6 位隨機數字密碼
        String tempPassword = String.format("%06d", new Random().nextInt(1_000_000));

        // 2. 計算 MD5 並更新資料庫
        String passwordHash = Md5Utils.encode(tempPassword);
        if (userService.updatePassword(userId, passwordHash) == 0) {
            throw new BusinessException("臨時密碼生成失敗");
        }

        // 3. 發送通知(即時通/簡訊/郵件)
        String xml = buildNotificationXml(userId, tempPassword);
        messageService.sendImMessage(xml);

        return Result.success();
    }

    private String buildNotificationXml(Long userId, String tempPassword) {
        // 實際專案建議使用 JAXB 或模板引擎生成 XML
        return "<SendMessage>" +
               "<UserId>" + userId + "</UserId>" +
               "<MessageTxt>您的臨時密碼是:" + tempPassword + ",請盡快登入修改。</MessageTxt>" +
               "<SystemName>後台管理系統</SystemName>" +
               "<Type>即時通</Type>" +
               "</SendMessage>";
    }
}

⚠️ 關鍵安全提示:MD5 不適合直接存儲密碼!

本文示範 MD5 僅為教學演示臨時密碼流程。生產環境用戶長期密碼必須使用慢速雜湊演算法:

演算法特點推薦參數
BCrypt自帶 Salt、可調成本因子、廣泛支援Cost 10-12(~100-300ms)
Argon2id記憶體硬化、抗 GPU/ASIC、現代標準時間 3、記憶體 64MB、並行 4
PBKDF2標準化、FIPS 認證、Java 內建迭代 100,000+、SHA-256
scrypt記憶體硬化、較早期方案N=16384, r=8, p=1

Spring Security 整合 BCrypt 範例


@Configuration
public class SecurityConfig {
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder(12); // Cost 12
    }
}

@Service
public class UserServiceImpl implements UserService {
    @Autowired private PasswordEncoder encoder;

    public void updatePassword(Long userId, String rawPassword) {
        String hash = encoder.encode(rawPassword); // 自動生成 Salt、雜湊
        userDao.updatePasswordHash(userId, hash);
    }

    public boolean verifyPassword(Long userId, String rawPassword) {
        String hash = userDao.getPasswordHash(userId);
        return encoder.matches(rawPassword, hash); // 驗證
    }
}

總結:密碼安全清單

  1. ✅ 使用 BCrypt/Argon2id/PBKDF2 而非 MD5/SHA 系列
  2. ✅ 每個密碼唯一 Salt(現代演算法內建)
  3. ✅ 成本因子隨硬體升級定期調高
  4. ✅ 登入失敗限流、鎖定、記錄審計日誌
  5. ✅ 密碼傳輸全程 HTTPS,前端可預哈希減少明文暴露
  6. ✅ 定期滲透測試與依賴掃描

記住:MD5 適合校驗檔案完整性、非安全場景雜湊;密碼存儲請用專門的慢速雜湊演算法。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved