簡體   English   中英

為什么 Spring 的 BCryptPasswordEncoder 為相同的輸入生成不同的輸出?

[英]Why BCryptPasswordEncoder from Spring generate different outputs for same input?

我正在使用具有 Spring 安全性的BCryptPasswordEncoder 我的期望是對於相同的輸入,我將始終獲得相同的輸出。 但是對於相同的輸入,我得到不同的輸出。 您可以使用以下代碼片段對其進行測試:

String password = "123456"; 
PasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); 
String encodedPassword = passwordEncoder.encode(password);
System.out.print(encodedPassword);

輸出:$2a$10$cYLM.qoXpeAzcZhJ3oXRLu9Slkb61LHyWW5qJ4QKvHEMhaxZ5qCPi

輸出 2:$2a$10$KEvYX9yjj0f1X3Wl8S.KPuWzSWGyGM9ubI71NOm3ZNbJcwWN6agvW

輸出 3:$2a$10$nCmrPtUaOLn5EI73VZ4Ouu1TmkSWDUxxD4N6A.8hPBWg43Vl.RLDC

有人可以解釋一下,為什么 BCryptPasswordEncoder 會這樣?

public static void main(String[] args) {
  // spring 4.0.0
  org.springframework.security.crypto.password.PasswordEncoder encoder
   = new org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder();

   // $2a$10$lB6/PKg2/JC4XgdMDXyjs.dLC9jFNAuuNbFkL9udcXe/EBjxSyqxW
   // true
   // $2a$10$KbQiHKTa1WIsQFTQWQKCiujoTJJB7MCMSaSgG/imVkKRicMPwgN5i
   // true
   // $2a$10$5WfW4uxVb4SIdzcTJI9U7eU4ZwaocrvP.2CKkWJkBDKz1dmCh50J2
   // true
   // $2a$10$0wR/6uaPxU7kGyUIsx/JS.krbAA9429fwsuCyTlEFJG54HgdR10nK
   // true
   // $2a$10$gfmnyiTlf8MDmwG7oqKJG.W8rrag8jt6dNW.31ukgr0.quwGujUuO
   // true

    for (int i = 0; i < 5; i++) {
      // "123456" - plain text - user input from user interface
      String passwd = encoder.encode("123456");

      // passwd - password from database
      System.out.println(passwd); // print hash

      // true for all 5 iteration
      System.out.println(encoder.matches("123456", passwd));
    }
}

生成的密碼是加鹽的,因此不同。

請閱讀encode()方法的文檔,其中明確說明密碼已加鹽。

緊跟在第二個 $ 之后的 22 個字符表示鹽值,請參閱https://en.wikipedia.org/wiki/Bcrypt#Description “鹽”是在散列之前添加到密碼中的一些隨機數據,因此具有給定參數的給定散列算法在大多數情況下會為同一密碼生成不同的散列值(防止所謂的彩虹攻擊)。

讓我們剖析原始問題中顯示的第一個輸出: $2a$10$cYLM.qoXpeAzcZhJ3oXRLu9Slkb61LHyWW5qJ4QKvHEMhaxZ5qCPi

  • $2a : BCrypt 算法的標識符
  • $10 : 輪數參數,這里是 2^10 輪
  • cYLM.qoXpeAzcZhJ3oXRLu :鹽(128 位)
  • 9Slkb61LHyWW5qJ4QKvHEMhaxZ5qCPi :實際哈希值(184 位)

鹽和哈希值都使用 Radix-64 編碼。

這是完全正常的,因為BCryptPasswordEncoder使用鹽來生成密碼。 您可以在此處此處閱讀有關“加鹽”密碼背后的想法。

這是文檔中對encode方法的說明

對原始密碼進行編碼。 通常,好的編碼算法應用 SHA-1 或更大的哈希值與 8 字節或更大的隨機生成的鹽值相結合。

BCrypt 輸出為:$2a$10$cYLM.qoXpeAzcZhJ3oXRLu9Slkb61LHyWW5qJ4QKvHEMhaxZ5qCPi

$2a$ 表示哈希算法

10$ 是日志輪次

以下是鹽和散列密碼

由於 Spring 每次都會生成不同的鹽,所以你的輸出是不一樣的。 您可以參考的 BCrypt 語法https://en.wikipedia.org/wiki/Bcrypt#Description

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM