How to prevent a password breach !

How to prevent a password breach !

2016 might go down in history as The Year of the Breach. The number of compromised companies is growing at an alarming rate and there seems to be newsworthy breach every week. The attack vectors are getting broader and the brand damage is increasing. It's interesting to compare the trade-craft of the organised crime, nation states and Skiddies (script kiddies), but it doesn't really matter at the end of the day when you're rolling incident response and your Public Relations team is in damage control, what matters is how you deal with the breach. The most damaging breaches are the ones that include huge data dumps of user credentials, which strikes at the heart of user confidence, leaving customers feeling betrayed and vulnerable. 

Computers only get faster and attacks only get better.

Well-known cyber criminals Peace listed 200 million records of Yahoo creds for sale on the dark web in August. This data included usernames and passwords that were only hashed using the md5 algorithm. Dropbox had 68Million records leaked later in the year, and the Panama Papers breach where an unprecedented leak of 11.5m files from the database of the world’s fourth-biggest offshore law firm Mossack Fonseca, sent shockwaves through the global political system, causing some political leaders to step down. 

How do you protect user credentials to prevent a breach ? 

How do you protect user credentials to prevent a breach ? My preferred option is to not host them. If you can use a federated Single-Sign-On product like MyWorkspace by Matrix42 then you don't need to store user credentials; therefore you don't need to protect them. It is more efficient to make your applications SAML compliant than to properly protect passwords. 

If you do need to host the credentials, hopefully this goes without saying, it’s a bad idea to store plain-text passwords, even temporarily. If a database containing plain-text passwords is leaked, user accounts are instantly compromised. 

To derive a good protection mechanism we first have to look at the attack tools. A modern commodity CPU can generate millions of SHA256 hashes per second, Specialised GPU clusters can calculating hashes at a rate of billions per second, FPGA boards and custom ASIC chips accelerate this further. So if you are only hashing the passwords with SHA or SHA256 it offers minimal protection from an unsophisticated attacker. You need to increase the workload for the attacker, and you need to layer the protections. 


Ring 1 : Hash the password. Use a strong one-way hash function like SHA512, to protects the password and produce a fixed-length 512-bit output. This makes it much easier to pass into other crypto functions as it eliminates truncation and padding issue. 



Ring 2 : Increase the workload. There are a few options here and the best approach is hotly debated, but for my reference design, I'm using bcrypt. You can use pbkdf2, bcrypt, scrypt or argon2, depending on which crypto-religion you follow. The main goal of these hash functions is to ensure proof-of-work. These functions significantly increase the cost, and time, of an attack.

The SHA512 output is hashed using bcrypt with a unique, per-user salt and a work factor of 10. The salt is stored with the result and is used to protect against rainbow table attacks. bcrypt is based on the Blowfish cypher and designed to be slow and difficult to speed up. 

Ring 3: The resulting bcrypt hash is encrypted with AES256 using a symmetric key known as a Pepper. Base64 the output to help you better manage the cypher text. This might seem like overkill, but the work factor required to crack this is so high it's almost impossible, while the implementation cost is negligible. The pepper must not be stored in a database and should be difficult to discover by anyone. 

You can hardware-derived the key, store it in volatile memory, secured it with a HSM or embedded into an encryption module, just make sure it's very hard to find. As a result, the credential data is of no use to an attacker if the cypher text is leaked on the internet. 

The use of SHA512bcrypt, and AES256 together is a solid and robust reference design for securing credentials. Computers only get faster and attacks only get better, so this approach allows you to dial-up or swap-out components as needed. You should consider additional safeguards against online brute-force attacks like failed login limits, rate-limiting password attempts, two-factor authentication and captchas. 

Why did I pick bcrypt ?

The only difference between the hashing methods mentioned is the memory consumption, PBKDF2 is lite on memory, but bcrypt, scrypt and argon2 are memory-bound functions that need increasing amounts of it. Most cracking rigs don't have much memory so this increases the attack cost, but also increases the hardware cost for you if you want to support the same number of concurrent authentication requests. I've chosen the middle ground of the CIA triad between security and availability. If you want the lite option choose for PBKDF2, and for brute strength choose argon2, which won the Password Hashing Competition

I'd love to hear what you think of the reference design, so please comment.

Edit : Title change from "How to securely store passwords" to "How to prevent a password breach !" - I need to work on my titles.

Michal ?pa?ek

Security engineer & hacker, web developer, speaker and consultant

8 年

Hi Wayne, thanks for the post. I've already commented under the Peerlyst post, but I feel like I should do it here too. Sorry for cross-commenting, though. I'd not recommend using Ring 1 at all, or it must be significantly improved to not make the password storage weaker. Here's why: The thing is that these hashing functions were not designed to be used together. Using SHA-512 will create 128-byte hex-encoded output, which will be truncated to 72 bytes when used with some (most?) bcrypt implementations. If the reason of Ring 1 is to eliminate truncation it has failed. If the output from SHA-512 is binary (not hex-encoded) then there's another issue of truncation: some (the ones that use C implementation at least, like PHP) bcrypt implementations truncate on zero bytes. There's a certain probability there will be a null byte in the SHA-512 binary output. Again, if the reason of Ring 1 is to protect against truncation it has failed. So, what should be done instead? Nothing, don't pre-hash. Or if you feel like designing your own crypto then use hex output, or Base64-encode the binary output, but choose the pre-hashing function wisely so that truncation does not occur. It always does with SHA-512. The pepper mentioned in Ring 3 is something different, not the encryption key. Don't call an encryption key a pepper. What's known as "pepper" is what's added before hashing. Encryption key is not added before hashing. encryption key is just that, an encryption key. Pepper is more of a static salt, and again, hashing functions are not designed for static salts. Don't use static salts, also known as peppers. Encrypting hashes is fine at least if you use an AE mode (or Encrypt-then-MAC) and are able to avoid any side-channel attacks.

回复
Wayne Phillips

SOC automation | AI SIEM | Generative AI Threat Hunting | Digital forensics and incident response.

8 年

Thanks Jan, I appreciate the feedback.

回复
Wayne Phillips

SOC automation | AI SIEM | Generative AI Threat Hunting | Digital forensics and incident response.

8 年

Thanks Jano. Crypto is a passion I share with most F5 engineers. Protecting passwords is hard, but federating with MyWorkspace is easy. If you have to store passwords then do it properly. This is a reference design for newbies, so they don't BASE64 encode a string and think it's secure.

Jano Van Deventer

Architecting security solutions across APJ

8 年

So just a hobby then, Wayne?

要查看或添加评论,请登录

Wayne Phillips的更多文章

社区洞察

其他会员也浏览了