比較密碼!jBCrypt的checkpw如何用常量時間比較抵御時序攻擊)
別再用String.equals()比較密碼jBCrypt的checkpw如何用常量時間比較抵御時序攻擊【免費下載鏈接】jBCryptA Java implementation of OpenBSDs Blowfish password hashing code項目地址: https://gitcode.com/gh_mirrors/jb/jBCrypt存密碼這件事很多 Java 開發(fā)者都會踩同一個坑拿String.equals()去比較用戶輸入的密碼和數(shù)據(jù)庫里的密文。這個看似人畜無害的習慣其實會通過耗時的細微差異悄悄泄露密碼信息。而 jBCrypt 的checkpw方法用了一個巧妙的常量時間比較技巧從根上堵住了這條漏洞。本文帶你搞懂時序攻擊的原理并手把手教你用 jBCrypt 安全地校驗密碼。為什么用 String.equals() 比較密碼很危險先弄清一個概念時序攻擊Timing Attack。String.equals()的底層實現(xiàn)是短路比較——從第一個字符開始逐位比對一旦發(fā)現(xiàn)不同立即返回 false。這意味著輸入z開頭的密碼和存著pass...的密文比較第 1 個字節(jié)就失敗速度最快輸入pa開頭第 3 個字節(jié)才失敗稍微慢一點攻擊者反復嘗試、統(tǒng)計響應耗時就能像玩猜詞游戲一樣逐字節(jié)逼近正確密碼比較方式行為耗時特征風險String.equals()逐位比較首個不同處即停止前綴越像耗時越長可被時序側信道利用jBCryptcheckpw全程遍歷XOR 累積比較無論對不對耗時恒定抵御時序攻擊對于普通場景這點微秒級差異可能被噪聲掩蓋但在密碼校驗這種被攻擊者無限次調用的場景下統(tǒng)計幾百上千次請求后信號就足以浮出水面。jBCrypt checkpw 常量時間比較源碼解析jBCrypt 是 OpenBSD Blowfish 密碼哈希算法源自 Niels Provos 與 David Mazieres 的《A Future-Adaptable Password Scheme》的 Java 實現(xiàn)核心代碼只有一個文件src/main/java/org/mindrot/BCrypt.java??碿heckpw方法約第 761 行的關鍵邏輯String try_pw hashpw(plaintext, hashed); // 用庫中密碼 已有鹽重新哈希 // ... byte ret 0; for (int i 0; i try_bytes.length; i) ret | hashed_bytes[i] ^ try_bytes[i]; // XOR 累積不提前退出 return ret 0;兩個精妙之處重哈希而不是比明文hashpw(plaintext, hashed)會從已存儲的哈希串里自動提取鹽和成本因子對候選密碼重新跑一遍完整哈希得到一個新的完整哈希串再比對。整個過程的重頭戲是crypt_raw約第 610 行中 2^cost 輪的 Blowfish 密鑰擴展計算開銷極大且恒定。XOR 累積比較循環(huán)把每一位的異或結果累積進ret即使第一個字節(jié)就不匹配循環(huán)也會老老實實走完全部字節(jié)。耗時只取決于字符串長度與有多少前綴相同無關——攻擊者拿不到任何逐字節(jié)的反饋 ??♂?順帶一提gensalt()約第 714 行用SecureRandom生成 16 字節(jié)隨機鹽保證同一個密碼每次哈希結果都不同防止彩虹表攻擊??焖偕鲜?步用 jBCrypt 安全存儲與校驗密碼第1步引入依賴在pom.xml中加入 Maven 依賴坐標見 README.md 與pom.xmldependency groupIdorg.mindrot/groupId artifactIdjbcrypt/artifactId version0.3/version /dependency也可以克隆源碼本地構建git clone https://gitcode.com/gh_mirrors/jb/jBCrypt第2步注冊時哈希存儲String hashed BCrypt.hashpw(password, BCrypt.gensalt()); // 或指定成本因子越大越慢、越抗暴力破解默認 10 String hashed BCrypt.hashpw(password, BCrypt.gensalt(12));成本因子按 2 的指數(shù)增長每 1 耗時翻倍。新項目建議 10~12登錄接口響應時間在 200ms 左右比較合適。第3步登錄時校驗if (BCrypt.checkpw(candidate, storedHash)) { // 密碼正確 }三行代碼零樣板。單元測試參考src/test/java/org/mindrot/TestBCrypt.java。常見疑問速答為什么每次登錄都要跑一遍完整哈希這正是 bcrypt 的設計目的讓試錯本身就很貴默認成本 10 約需百毫秒級暴力破解成本因此抬高數(shù)個量級。成本因子以后能升級嗎可以。檢測到舊哈希的成本因子低于當前標準時校驗通過后用新參數(shù)重新哈希并更新存儲即可。jBCrypt 能兼容其他系統(tǒng)的 bcrypt 嗎可以。它實現(xiàn)的是標準$2a$格式hashpw會校驗鹽的版本前綴與 OpenBSD、PHP、.NET 等生態(tài)互通。許可協(xié)議ISC/BSD 寬松協(xié)議見LICENSE可放心商用??偨Y密碼校驗安全清單? 永遠不要用String.equals()/比較密碼或任何機密? 使用 jBCryptcheckpw這類恒定耗時比較XOR 累積、不短路? 用SecureRandom鹽 可調成本因子的自適應哈希bcrypt/scrypt/argon2 同族? 數(shù)據(jù)庫只存哈希串絕不存明文哈希串本身可放心外泄? 登錄接口疊加速率限制與鎖定策略進一步抬高在線攻擊成本把比較這個看似無害的小步驟做對你的密碼體系才算真正閉環(huán)了?!久赓M下載鏈接】jBCryptA Java implementation of OpenBSDs Blowfish password hashing code項目地址: https://gitcode.com/gh_mirrors/jb/jBCrypt創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考