> An alternative approach is to hash the passwords as usual and then encrypt the hashes with a symmetrical encryption key before storing them in the database, with the key acting as the pepper. This avoids some of the issues with the traditional approach to peppering, and it allows for much easier rotation of the pepper if it is believed to be compromised.
It sounds to me that this is the actual recommendation and the other method is more for explaining the traditional approach. Also the two-way function has a clearly stated benefit in this case.
The whole idea is to have a factor that is never stored in the database, so a database dump cannot expose hashes that can be attacked. Just as the user may want to change their password periodically, the site operator might want to change their pepper. Without a 2-way function, you can't do that without the user presenting their unencrypted password again.
What do you mean by "unlike" in this case? You're storing part of the password locally and getting part of the password from the user. If you don't trust your hashing function enough to do that, why do you trust it for the password in the first place?
Or specifically - are you worried about common prefixes in this case, or something else?
In this case I’m not worried about any specific attacks. Knowing how most password-hashing algorithms are built, it’s probably completely safe to do so. But these tools weren’t necessarily designed with this method of use in mind and haven’t been analyzed extensively with it either, and that should give anyone pause. If they had, they would—like argon2—have a specific input parameter for this purpose.
For what it’s worth, sometimes even like inputs can’t be smashed together safely. For instance HMAC(k, a a| bb) doesn’t uniquely authenticate aa and bb if they’re all or partly user-controlled, since it’s identical to HMAC(key, a | abb) and HMAC(k, aab | b).
The point being, concatenation of inputs to cryptographic functions is often not a safe operation. Triply so when it’s being used to naïvely add a “feature” to a tool that lacks it (e.g., the classic broken example of SHA(key | message) as a poor-man’s HMAC).
Likewise, I’m not a fan of encrypting password hashes since there’s no need to have a two-way function for password verification. Again, there’s probably no exploit. But over and over again we’ve seen ways where attackers have been able to exploit systems where a primitive was used for a subtly different problem than the one it was designed for.
Much better: HMAC the password with the key before running it through the hash.