Home » Posts tagged "pbkdf2"

NIST 新的密碼規範

NIST 所提出來的規範 (Special Publication 800-63-3: Digital Authentication Guidelines),雖然還在 Draft 階段,但可以看出目前密碼規範的趨勢跟以前的不同:「NIST’s new password rules – what you need to know」。

整份規範可以在 GitHub 上讀到,不過 markdown 好像沒處理好,直接在 GitHub 上看到的有點亂,不過還算看得懂就是了...

在 NIST 網站上有 html 版本「Digital Authentication Guideline: Public Preview」可以讀,應該會好一些。

整份 guideline 很長,密碼的部份主要是在「DRAFT NIST Special Publication 800-63B Digital Authentication Guideline」這份裡面關於「Memorized Secrets」的部份。


  • 有「安全問題」反而會讓系統安全變弱。
  • 要求使用者有大小寫、特殊符號這種讓使用者更難記密碼的限制,反而會讓使用者選出更差的密碼。讓使用者自由選擇密碼,同時用黑名單機制把常見的密碼擋下來會是比較好的選擇。
  • 定期換密碼反而會讓使用者選擇更差的密碼 (因為要花力氣記,所以會選擇簡單的密碼),不如讓使用者選一個強一點的密碼一直用。同時要合理設計限制登入錯誤的機制。
  • 絕對不可以存明碼。

下面開始 copy & paste 然後給簡單的註釋...

首先是對最低長度的定義,至少要八碼。而對最大長度的限制是「至少你要讓使用者可以輸入 64 碼」:

Verifiers SHALL require subscriber-chosen memorized secrets to be at least 8 characters in length. Verifiers SHALL permit user-chosen memorized secrets to be at least 64 characters in length.

密碼不應該限制特殊字元,只要可以印出來的 ASCII 與空白都應該被允許,而 Unicode 也應該要被允許:

All printing ASCII [RFC 20] characters as well as the space character SHALL be acceptable in memorized secrets; Unicode [ISO/ISC 10646:2014] characters SHOULD be accepted as well.


Verifiers MAY remove space characters prior to verification; all other characters SHALL be considered significant.

要注意的是,為了強度,每一個 Unicode 應該只算一個有效字元:

For purposes of the above length requirements, each Unicode code point SHALL be counted as a single character.


Memorized secrets that are randomly chosen by the CSP (e.g., at enrollment) or by the verifier (e.g., when a user requests a new PIN) SHALL be at least 6 characters in length and SHALL be generated using an approved random number generator.


Memorized secret verifiers SHALL NOT permit the subscriber to store a “hint” that is accessible to an unauthenticated claimant. Verifiers also SHALL NOT prompt subscribers to use specific types of information (e.g., “What was the name of your first pet?”) when choosing memorized secrets.

然後針對已知的弱密碼 (像是字典單字,以及之前被洩漏出來的密碼) 都應該擋下來:

When processing requests to establish and change memorized secrets, verifiers SHOULD compare the prospective secrets against a dictionary of known commonly-used and/or compromised values. This list SHOULD include passwords from previous breach corpuses, as well as dictionary words and specific words (such as the name of the service itself) that users are likely to choose. If the chosen secret is found in the dictionary, the subscriber SHOULD be required to choose a different value. The subscriber SHOULD be advised that they need to select a different secret because their previous choice was commonly used.

另外不應該要求使用者要特殊字元或是大小寫這種限制,而且也不應該要求使用者定期換密碼 (除非確認被破了):

Verifiers SHOULD NOT impose other composition rules (mixtures of different character types, for example) on memorized secrets. Verifiers SHOULD NOT require memorized secrets to be changed arbitrarily (e.g., periodically) unless there is evidence of compromise of the authenticator or a subscriber requests a change.

另外禁止用明碼存密碼,必須用 PBKDF2 這類可以防禦快速離線計算的演算法:

Verifiers SHALL store memorized secrets in a form that is resistant to offline attacks. Secrets SHALL be hashed with a salt value using an approved hash function such as PBKDF2 as described in [SP800-132]. The salt value SHALL be a 32 bit (or longer) random value generated by an approved random number generator and is stored along with the hash result. At least 10,000 iterations of the hash function SHOULD be performed. A keyed hash function (e.g., HMAC), with the key stored separately from the hashed authenticators (e.g., in a hardware security module) SHOULD be used to further resist dictionary attacks against the stored hashed authenticators.


oclHashcat-plus 提供了透過 GPU 破解的 benchmark 數據:

可以看到 PBKDF2、sha512crypt $6$ 以及 bcrypt $2a$ 的速度慢得很漂亮 XD 不過 SHA512 的速度比 SHA256 慢不少倒是頗意外...

PBKDF2 的使用率很高 (因為無線網路 WPA/WPA2 的規格),所以各語言的普及率也高不少,如果要找個標準來用的話,PBKDF2 相當不錯...

htpasswd 的 SHA 不會帶 salt (seed)...

剛剛發現 htpasswd (Apache.htpasswd 檔案產生程式) 提供的 SHA-1 不會使用 salt,不過 MD5 格式會...


gslin@colo-p [~] [17:44/W7] touch test.txt
gslin@colo-p [~] [17:44/W7] htpasswd -b -m test.txt test1 test
Adding password for user test1
gslin@colo-p [~] [17:44/W7] htpasswd -b -m test.txt test2 test
Adding password for user test2
gslin@colo-p [~] [17:44/W7] htpasswd -b -s test.txt test3 test
Adding password for user test3
gslin@colo-p [~] [17:44/W7] htpasswd -b -s test.txt test4 test
Adding password for user test4



依照說明,htpasswd 使用的 SHA 是移植自 Netscape server 的 LDAP Directory Interchange Format (ldif):

Use SHA encryption for passwords. Facilitates migration from/to Netscape servers using the LDAP Directory Interchange Format (ldif).

在安全疑慮 (Security Considerations) 上也有註明 htpasswd 使用的 SHA 是不帶 salt:

The SHA encryption format does not use salting: for a given password, there is only one encrypted representation.

現在密碼儲存應該是朝 bcryptPBKDF2 發展,參考依林姊姊的「請愛用 bcrypt 和 PBKDF2」,後者 PBKDF2 被用在 WPA2 上。