salt = urandom(16)
pepper = "oFMLjbFr2Bb3XR)aKKst@kBF}tHD9q"
# or, getenv('PEPPER')
hashed_password = scrypt(password, salt + pepper)
store(hashed_password, salt)
That is an algorithm, which composes bcrypt with pepper.The idea of not using key-rotation alone is insane, but lets just focus on your last point
Also, I'm confused at how the proposed alternative would be harder to get wrong
Really? AES literally has hardware support, and can be done in a single call, and has been studied for years. How can that reasonably be considered "harder" to get wrong than something proposed by some random guy on the interwebs?Outside of Peer-Review, what reason would anyone have to use the pepper scheme? As others have posted, there are several community members who's opinions do matter due to extensive research and body of work
For password hashing purposes, salt doesn't need to be uniformly random, the only requirement for salt is to be unique and unpredictable to the attacker (see http://crypto.stackexchange.com/questions/6119/hashing-passw...). Most password hashing functions use a cryptographic hash on salt.
This particular function, scrypt, uses one-round PBKDF2-HMAC-SHA256 to mix password and salt:
https://github.com/golang/crypto/blob/master/scrypt/scrypt.g...
PBKDF2 feeds salt, basically, into SHA256:
https://github.com/golang/crypto/blob/master/pbkdf2/pbkdf2.g...
But PBKDFs like bcrypt and scrypt are not designed to keep the salt parameter secret; in fact they assume the attacker knows the salt. And so if they happen to reveal the salt to the attacker, this is not considered a bug in the algorithm and won't have been flagged or fixed by cryptographers.
1) You should not invent your own algorithm. That's a given. That's why you use bcrypt/scrypt.
2) It's not abusing the algorithm, it's using a longer salt (in the concatenation case).
3) There's nothing wrong with nesting algorithms (just remember to use hex/base64 encodings, not binary). For example Facebook passes passwords through half a dozen algorithms. They call it the "onion". And it includes a pepper.
4) As for being effective, I think the SQL injection case speaks for itself.
5) As for rotation - just don't do it. You pepper gets compromised? Who cares, add a new one on top of the old one.
Also, I'm confused at how the proposed alternative would be harder to get wrong:
> Encrypt The Output Hash Prior To Storage