phpstorm.dev

PHP ecosystem insights

PHP knowledge

Versioned PHP knowledge with primary sources and explicit verification dates.

Source checks through 2026-10-14 · 56 sources

Verified 2026-10-05 discussion Permanent entry

PASSWORD_BCRYPT_SHA256 for password_hash() proposal

Under discussion; not accepted. The official RFC index lists this RFC under discussion (it was listed as a draft on 4 October). At 09:20 UTC on 5 October the author announced the RFC on the internals list. After a page edit at 13:13 UTC the RFC page also reads Under discussion (still version 0.1) and links that announcement as its discussion thread. The earlier conflict between the page header (Draft) and the index is therefore resolved. The voting thread is "tbd", the changelog still has only the 2026-10-04 entry, and no vote has been opened. The author is Sjoerd Langkemper, who also wrote the 72-byte rejection proposal.

What is proposed

The RFC adds a new, opt-in password_hash() algorithm identifier, PASSWORD_BCRYPT_SHA256 (value "bcrypt-sha256"), plus PASSWORD_BCRYPT_SHA256_DEFAULT_COST = 12. The password is first run through HMAC-SHA256, keyed with the 22-character bcrypt salt string. The base64-encoded digest (44 bytes) is then passed to bcrypt. That input can't contain NUL bytes and is far below bcrypt's 72-byte limit, so long passwords are no longer truncated.

The vote, when opened, is planned as one question needing a 2/3 majority. The proposed version is the next PHP 8.x ("e.g. PHP 8.7").

Relationship to the 72-byte proposal

This RFC follows from the internals discussion of the 72-byte rejection proposal, where Tim Düsterhus suggested Passlib's construction instead. The new RFC calls that proposal and php-src PR #21675 (a Blowfish NUL-byte fix) "previous attempts", and rejects changing PASSWORD_BCRYPT itself as too risky. In the 5 October announcement, the author wrote that the 72-byte proposal had drawn "much criticism because of its backwards incompatibility" and that they did not think it "is worth pursuing further at the moment". The official index now lists that RFC as inactive. Neither proposal is accepted.

Discussion so far

In the thread on 5 October, Tim Düsterhus supported the proposal, citing Passlib as precedent. He also argued that the RFC overstates the NUL-byte problem, because PHP already throws ValueError when a new password contains a NUL byte. He asked separately whether the $2b$ bcrypt identifier should be supported, saying he understood it to be identical to $2y$. Another participant asked for a separate "rounds" option. Tim Düsterhus replied that bcrypt's rounds and PHP's cost are the same parameter, and that keeping the name cost matches PASSWORD_BCRYPT. These are list comments; the RFC text had not changed in response when it was inspected on 5 October.

On 8 October Mirco Babin raised three objections:

The author replied by asking for a standardized alternative with better interoperability, mentioning PBKDF2, which NIST standardizes but which they called generally less resistant to offline cracking than bcrypt. A participant who signs as Andrey objected to the pace. They said the PR had been written a day after the idea was raised, and asked for time because they have been working on an alternative for weeks and hope to publish it in a week or two. No alternative RFC page was seen. The RFC page inspected on 8 October was unchanged (version 0.1, Under discussion, voting thread "tbd"). On 9 October Rowan Tommins replied to the OWASP objection. They said the "password shucking" attack it describes needs the same inner hash to exist elsewhere for that user, which with a per-hash salted HMAC would need the same password and salt. In their view the salt plays the role of the OWASP pepper. They also noted that OWASP recommends a 72-byte maximum password length, as the inactive length RFC did. The objector replied that such questions belong with OWASP, and that following standards and interoperability is what PHP should offer. Rowan Tommins answered that they had asked no questions. They concluded that the OWASP page describes a weakness in similar algorithms and that the proposed algorithm, while not identical to the OWASP suggestion, addresses the same weakness differently, so it is "worth considering further". These are list opinions; the RFC page was not re-checked in this cycle.

Implementation

The implementation is php-src PR #24073, opened on 2 October 2026 and now titled "ext/standard: bcrypt-sha256 password hash". GitHub labels it "ABI break", and on 2–3 October a core reviewer requested changes, mostly to the tests. As of 8 October it is still open, not marked as a draft, and not merged (last updated 6 October).

Limitations

This page summarises a draft proposal only. Names, format details and the target version can change, and nothing here is available in released PHP. For today's behavior, see bcrypt length limits.