 Good afternoon, good evening, or even good morning depending on which part of the world you are listening this talk from. And no, it does not get old. I still want to give a huge shout out to the crypto village organizing community for making this virtual con happen for us. Welcome to the second talk of the day from my side. In this talk, I'm going to touch base upon how to stores in for sensitive information securely so that we can safeguard it reasonably well against any kinds of offline cracking attempts. And before we go ahead, I'd like to introduce myself. I'm Anshit Sheth. I work as a security researcher at a leading static analysis company called Veracord. My primary responsibility here is to be on top of the latest and greatest happenings in the security field more specifically in the application security domain and transfer that knowledge to make sure our customers are safe. I'm a huge crypto enthusiast, I have spent a lot of time, or actually the reasonable amount of time understanding different base crypto blocks. It's practical implementations how it can be used in real world. I understand a lot of anti patterns. I've spent a lot of time looking at different crypto implementations across programming languages. And I tried to translate all this expertise into making sure our customers core bases are safe and to help pick up any anti patterns. Recently, I got thinking, why are we seeing so many data breaches in the first place? Eventually, I realized, okay, this is going to be a matter of when rather than if. So what can we do to protect this information once it is already breached, mainly from any kind of offline cracking? How can we make the information cracking process very, very expensive that it is almost useless? So in that quest, first place, I'll definitely go for that matter of which first thing comes to anyone's mind would be our Troy Hunt's most organized, most informative site about this called Havibene Point. In this site, he keeps a database of all the breaches which has happened in probably last decade and gives out information about what might have happened, what has happened, and all those kind of neat stuff. So instead of putting a big slide of shame kind of thing like who got hacked and what were the reasons and stuff. What I tried to do was look at all the domains which were hacked and what kind of mechanism were they using for storing any kind of sensitive information. So this is what my analysis says. There were around 453 unique domains, 13% were storing it in plain text, 20% as hashes without any salting, 30% as salter hash, around 15% still using a key derivative functions which is a great step and roughly 23% decided not to disclose which in my opinion is plain text. But no judgments here. So like looking at it I was thinking okay why were they breached in the first place. Most of the times it was because they did not pay a lot of attention in other kinds of security issues in their applications. A lot of them were simple SQL injections where entire databases were dumped out. Open S3 buckets was not an uncommon thing I saw. There were a lot of unprotected endpoints which kind of leaked this data. So that was my first lesson learned that why are these things happening. And now then mainly my focus was towards thinking about okay this breach has already happened or these breaches are always going to keep happening for even for innocent reasons sometimes. Well there is nothing innocent about security. So my next thing was okay now what can what happens after these breaches are done. And my first thought was like oh wow the modern computer architecture is getting cheaper and cheaper and it's going to keep getting cheaper from now on. All this modern GPUs with extremely high parallelization capabilities can craft these things in minutes and making the cost much more making the password cost much cheaper for any kind of offline mechanisms. With the whole bitcoin mining philosophy of cracking there are so many A6 application specific integrated circuits out there which makes the cost of cracking much more cheaper. There are literally trillions of hashes happening within seconds and this can be easily mapped to any kind of crypto parameters. All these things are going to keep making password cracking much more cheaper with time. So what should we do? Well the need of the hour was always stretching this information out so that it takes we have to throw a lot of computational resources like CPU and memory to compute each password. With that we are going to increase the speed with which the passwords are being calculated. This will greatly increase the offline cracking time and making us silent towards any kind of modern computer architectures or boot forcing or any kind of time memory trade off attacks or rainbow tables dictionary attacks all those kind of things. So that's what we really needed. And how did we achieve that is using key derivation functions. Well, this concept of key derivation function isn't specific to password hashing or secret information hashing. In fact, it came into existence for actually creating key material out of low entropy inputs. But at that time when everyone were in this cat and mouse race, people thought that KDFs are much better suited than just simply storing things as plain hashed or salted hashes. It can be much better safeguarded at that time. So, and thus this whole philosophy of using key derivation functions KDFs came into picture. So, simply how this works. Well, underlying there is still algorithm which is used which is iterated hundreds and thousands and sometimes a couple of millions of times on a basic crypto primitive. This type of functions are called adaptive functions. And then much more matured ones are throwing a little or sometimes a lot of memory to this iterative process which increases or almost quadruples the speed of cracking offline. And still it takes password and sort gives out a fixed length hash. And it's the work factor which is which can be tuned based on different hardware your application is being deployed. So that's going to be the base of our talk today to protect our safeguard against most of the offline cracking mechanisms. Some design considerations I'd like to point out here is try to save your password hash and salt in completely different databases like or a distributed database or like maybe a database and a property file or something. They should not be close to each other. Obviously you're not going to store a password in plain text anymore. I can even go as far as saying that maybe we can have different works or work factors for different information we are trying to safeguard or even like different logins can have different work factors and storing work factor for logging obviously. With increasing cost in memory or CPU. It should be routinely checked that our work factors are incremented accordingly to keep making password offline cracking expensive. Lastly, how expensive should be is tolerable or acceptable. Industry standards are any kind of interactive login a latency of around one second is very acceptable. So make sure you tune your work factors in a way that the output is calculated around a second. This is acceptable latency and it still increases the offline cracking time by a huge margin. Lastly, if you are using your password of trying to save a password which is not going to be involved in interactive logins like for example your hard disk encryption. A latency of around 5 to 6 seconds is quite acceptable in that scenario. So those are the things I'd like to say about key derivation functions in general. Let's start talking about different key derivation functions in existence starting with adaptive functions. One of the oldest and the most widely adopted function was PBKDF2. Again, it came into picture because they really needed to generate keying materials. This function is the only government approved function right now. So if you really have to comply by government standards, I really wish you don't. Then this is probably your only option unfortunately. This function is also used as a different crypto primitive blocks for other modern functions in these days. Let's see how this actually works internally. So just like our generic KDF working, it still takes a password assault, gives out a password hash. You can actually configure the size you expect out of a password hash. This feature was more for because there is always requirement of a fixed key size for any kind of block cipher being used for. The work factor is in terms of iteration count. Let's talk a little bit about the internal working of this algorithm. What it does is it runs the crypto primitive, it iterates over is a pseudo random function, usually a HMAC. Based on the desired output length and the block size of the internal hash being used in the HMAC, different blocks are generated and those blocks are iterated for the iteration number of count times output is concatenated and that's your password hash. So you will see things a little bit in green color here. What I have done is I have written a tool which will do parameter tuning for me based on the rules of thumb. I mentioned earlier about having a password being calculated roughly one second for interactive logins and roughly five seconds for any kind of non interactive logins. Since PBKDF is a government approved, they say the iteration count or the work factor for this algorithm should be around 10,000. Which is way lower and please don't do that, please increase something. For a reasonable hardware on which most of the typical web applications would be deployed in today's time, EC2T2 instance with roughly 8 GB of RAM and x86 architecture. I ran this tool and the number of iterations were around 1.5 million for just one second of password calculation. Just imagine how off the government standards are here. So I'll highly motivate whichever algorithm you decide to use among all the algorithms you're going to talk about. Please run some kind of a tuning utility player on which your parameters I'll be open sourcing this tool. Anyways, you can feel free to grab it and run it on your deployment hardware to tune your work factors accordingly. Some things you should be worried about when choosing this algorithm is please choose your password output length little less than or equal to the internal hash you're using. The reason being it unnecessary takes a lot of processing power for a no value add. So that's one of my suggestion. In this algorithm, you can just configure the CPU time involved. There is no memory involved. It is still not at all silent towards any kinds of brute forcing attempts because of the highly parallelized nature of a very, very cheaply rentable GPUs in today's time. If you don't have to comply back with the government standards, please move on, use some better memory hard functions. Next, a notable mention, Becrypt, still one of the one of it's very commonly used. It is based on already deprecated a symmetric algorithm, a symmetric Cypher called Blowfish. It involves a little bit of memory for its internal working. So that's what is slightly better than PBKDF. But again, that memory or amount of memory we need or use is not tunable by the user. And again, it was designed for generating key materials and not with storing secrets or password hashing in mind. So how does this algorithm work internally? Again, we have a password fixed size salt password output as a password hash iteration count is specified in logarithmic way. So this is going to be to reach to 14 number of iterations. And internally how it works is it has this very expensive blow cypher based blow cypher key setup process, which involves some memory. So it rates around that key setup and the output is again iterated through a normal blow cypher blowfish algorithm. And the output is given to the caller. It still is a little better than PBKDF because of the internal RAM usage. But it is still very susceptible to brute forcing attacks, maybe a slightly more expensive than the previous one. And I don't understand why to use Becrypt though I've seen a lot of usages of that. If you don't have to even comply by the government standards, why not use the more modern memory hard functions? Okay, let's start talking about a few different memory hard functions. The first one being a script. It's one of the very earlier generation memory hard memory hardness built inside the function. It is having an increased adaptation in cryptocurrencies, mainly due to the nature of it and cryptocurrencies. They don't really need to worry about a time memory trade off attacks like offline cracking needs to and cryptocurrencies needs to be more worried about side channel attacks, which is not a domain for offline cracking. So it's mainly due to the nature of the applications. It's widely adopted in cryptocurrencies. It's not like it's better or less secure for other applications. It was still designed for key material, but it saw a lot of promising breakthroughs in being used for offline cracking. Okay, let's see how this works. It still has password, salt output password we are given. We can still configure the length we desire out of the output. And if you see the work factor has increased from one to almost three at this point. And not all are going to be still giving us all the freedom to tune all kinds of resources, but that's a huge step in the right direction in my opinion with memory hardness involved. That is parallelization, you can paralyze the computation. I would like to note here that not all implementations give this control to the user. They still do it the way it depends on the implementation. You would note that there is only one parameter which will control both the CPU resources as well as the memory involved. Basically it does not differentiate between it between both the resources we can throw at this algorithm. So basically going down the line if we decide that memory is getting cheaper so we should increase the amount of memory being used in the algorithm. We don't really have a choice here. And finally is the block size which is used internally. Most typical values are 8 or 16 does not make a huge difference. So that's okay. Let's talk a little bit about how the algorithm works internally. As we were talking about and while talking about PBKDF, it is used internally from Mac to generate a fixed size password which is looped through this crazy memory array with a lot of stream ciphers and XORing going on for the iteration number of count. And again the output is made a fixed size by PBKDFing it again and output is passed to the caller. If you are choosing this, well this reduces the time or any kind of brute forcing attempts by a huge margin compared to adaptive functions. But the way the memory is being used by the algorithm internally, it is still using adjacent memory arrays in the consecutive operations. What I'm trying to say is depending on the value of the password, the consecutive arrays are chosen. So this is always going to be a predefined sequence of memory arrays based on the input password. And what this opens us is towards the side channel attacks. Again as we spoke about earlier there is no way we can tune the CPU and memories independently. And since there is a lot of crypto involved in this algorithm like we saw we have HMAC, we have PBKDF, we have Salsa, stream ciphers, we have XORing, we next again have PBKDF. The number of crypto involved increases, the implementations become more complicated, more error prone, the crypto analysis becomes more complicated and it's not as sleek basically. So these are the things you should think about if you decide to go with a script. There is still a huge step ahead of the adaptive functions. It still reduces the offline cracking caused by a huge margin almost like a quadruple based on the number of iterations. It's a great choice. Well, don't they say save the best algorithm for the last and that's what Argon2 is. Around 2015 there was this competition which took place and the goal of that competition was to come out with an algorithm which is specifically suited for storing secrets and safeguard it against any kind of offline cracking obviously. It wasn't like before that no one was thinking about how to safely store information. Well, the breaches were happening. It was more like a cat and mouse race and the industry started looking at what current tools are there in the cryptography arsenal which we can apply to this particular problem quickly so that they can safeguard their information as they can from any kind of offline cracking mechanism. Well, Argon2, the winner of this algorithm is obviously going to take care of all those existing attacks we have been talking about so far. It's very resilient against any brute forcing or dictionary attack. It's very hard to just parallelize it and run computations and start cracking passwords in minutes. It's also very resilient about the modern computer architecture which started maturing become much cheaper and they were very, very cognizant about it will keep getting cheaper with time. So it's obviously going to be it's very resilient against any application specific integrated circuit architectures or even FPGA arrays. Well, few years ago there were limited implementations of this algorithm out of a direct cryptographic library, but that situation has a greatly changed. So congratulations, you don't have to implement this algorithm yourself. You can pick up any programming language, any library in that language and for the most amount of time you would be having this implementation ready to be plugged and played in your application. So let's see how this algorithm works. Well, you still have your passwords and soils you still have will get a fixed length hashed password. In terms of memory factors, you have three parameters now. One is obviously parallelization you can configure it based on number of CPU cores you have at your disposal. And you can tune the amount of CPU needed in terms of number of iterations and the memory which can be used in this algorithm in terms of memory size. So it basically decouples both the resources resource utilizations very unlike a script and one of the huge advantages. There's some crypto analysis done on Argon to algorithms, which makes any iterations below 10, a little susceptible, but it is more theoretical crypto analysis or don't freak out but choose a parameter which is at least greater than 10. And that's the reason. Talking about modes of operation, which is crucial. There are two main types of modes in this algorithm. One is data dependent mode, which is what was there in the previous script algorithm as well and a data independent mode, which is the best option for password storage. And the third one is a hybrid of both the modes working together. How this modes work for that. Let's start talking about the internal crypto of this algorithm. So how it goes is it first computes a hash of password salt and all this different parameters. Any hash can be used. Usually it is a big two. And based on the value of the hash, sorry, before that there is this memory array which is dedicated to this based on the memory size we give. So just imagine it as rows and columns being populated iteratively for a number of iterations of times. Now after, so for data dependent mode and data independent mode, how it is different. It's like each memory array is being populated in sequence, but that sequence in data dependent mode is decided by the value of the hash, which is dependent on the value of the input password. And for data independent mode, it is completely random. So, so basically what it comes down to is the sequence of memory array populations per iteration is actually based on the input password. And this particular feature of this algorithm makes it susceptible to side channel attacks, which is okay for crypto currencies but not very comfortable for any kind of password storage. And that's why you should use the independent mode where the sequence of memory array population is completely random and it takes away even that issue which a script had and which even the this kind of attacks might have. So some design considerations, you have to tune your parameters a little more carefully and mostly because you have few more parameters to take care of. As we talked about the data independent mode is more susceptible to any kind of side channel attacks. And there is this hybrid mode where the first part of it is happening in independent manner and the next half is happening in the data dependent manner. And with that we get the best of both worlds. We are silent towards side channel attacks as well as we are much better with the time memory trade off issues. So that's what I would say use Argon to mainly into ID mode. We already looked at what is the best parameter options for an output for password computation within a second. Since Argon 2 is the algorithm I am highly recommending to be used for any kind of sensitive information storage. I like to quickly show how easy it is to just start using this by any implementations you have access to. I just to record this demo I had a 4x4 EC2 instance. These are the details of the instance. It's a typical standard T2 medium with two CPUs and four GB of RAM. Currently available as of this moment is around 2.8 gigs. It's using a x86 architecture on Linux kernel. So let's see how quickly this to start using this. Well I am going to use NaCl's password modules where the Argon 2 ID is being supported. Well a quick pro tip whenever given a choice of any crypto implementation you need. If you have a choice always go for NaCl. It's very cleanly written, written by cryptographers rather than actual developers. They are deprecate things which are no more secure or better options are available out there. They quickly deprecate all those things from anyone's view so chances of making wrong choices are eliminated. Okay coming back to the code we are going to use that module and just to keep track of time we are going to use the time module. Start time is going to be current time. Let's start storing the password. First let's use the module hash.argon 2 ID. Why not use the hybrid one best of both worlds right? And the string output for that giving the password along is better than higher entropy shorter one. So that's what I choose for. Arch limit is the number of iterations around the memory array. Let's go for 14. Around 10 is already theoretically crypto analyzed so anything about 10 is great. And the key thing memory. It's again logarithmically given. We already know the answer from our tuning tool. So let's see this is as short and sweet as it can get actually. And just to keep track of time let's see how much it is. And hopefully this compiles and runs actually. Okay so it took around 1.1 second. Can we go any higher? Let's see going from 27 to 28. Which is 2.3. I'll leave that choice to you at this point. This is how you should typically tune any parameters. It's almost a second nature to wonder how these functions actually compare against each other. There is not a lot of research done in this topic about how to actually put a dollar value or a number of years of cracking a particular breach mechanism. There is no apples to orange comparison as well you could imagine. But good notable work is being done by these two papers one released in use mix a couple of years ago and another one done in conjunction at between Microsoft and Purdue University. In the most trivial way what they do is they look at the latest hardware and the memory cost and just do a reverse or just start calculations from there. And that's what I tried to do it as of yesterday. So for adaptive functions it's just going to be again sorry again a huge list of disclaimers here before I actually talk about this very very cautiously actually is. I'm assuming the keyword the password the salt the output all those things are same across all these functions. I'm also assuming there is no electricity cost involved. Yeah. And so talking about these figures for adaptive functions it's just going to be as simple as number of iterations per cost of hardware and the cost of hardware would be is much easier to calculate these days because most of the modern a six hardware for Bitcoin mining come with that statistics. So looking at one of the most leading hardware in that department coming from and minor. They're one of the best configured one is around $2,500 and it promises to do 110 trillion hashes per second and trillion is 10 rest to 12 if you are wondering as I was. So using that that configuration with the number of iterations adaptive function is going to take so much time. The point being it's going to be extremely cheap to just crack these passwords, considering this decently priced machines are going to be in common people's hand very soon. And similarly for memory hard functions and I want to stress here that this is only for memory hard functions which is running in the data dependent work where the array used for memory memory calculations is based on the input passwords. So where again the cost is going to be more based on memory as well as the amount of time it takes which pretty much quadra person memory hardness. Is going to be much more expensive compared to adaptive functions, and this is just for data dependent mode for data independent more well the cost might still be the same but the number of guesses is going to be exponential. So this is just sharing some statistics still in a more conservative tone. This is all of what I wanted to speak about today around offline cracking different mechanisms we can use to safeguard ourselves key derivation function being the key of that how to tune different parameters. And what kind of design concentrations you should be doing while picking each one of that. Next I'd like to talk about the little bit about how all this information can be mapped to storing any kind of secrets you need to. For that you need to sit down and do a little bit of threat modeling for your own usage is something like what what is sensitive to your business. Do you need to comply by any GDPR requirements or are you storing any personally identify the information. Can it be used for crafting further attacks against users whose and whose information is might be breached. How are you storing that information are you storing in a database which fields are involved in that database all those things needs to be thought about and you can easily map. All this KDS to work for your own needs. Lastly, you must have come across countless countless suggestions and password hygiene requirements or tips over years since it is such a key aspect of any kind of authentication mechanism. I led just for the complete completeness of the stock I like to say a few things about it always choose a unique password password managers are great please use those longer passwords are better than shorter higher entropy ones. This is what I typically do is I store my passwords in a password manager. This is a configuration I use while generating any new password I choose a longer password and with a reasonable amount of entropy. The point I'm trying to make is there is a lot of crypto analysis done where which points us towards the points us towards the theory that longer passwords are better than shorter ones with higher entropy. So a password whose length is like say 25 or 30 characters is far better than a password which is of eight or 10 characters standard length with like two special characters one uppercase and two digits and those kind of things. So do that and the website we looked at about about the data breached information they have a nice API exposed by again Troy Hunt. It would be great to use that API in your websites or even password managers can start using that where if a used a password which is already been seen in a breach is being used then they would be flagged and and that could go a long way. Finally, in conclusion, please embrace adaptive key derivation functions, use memory hard functions based on your choice and comfort level with the amount of crypto analysis done. Please don't do plain text or hashing or your own DIY designs. Those are all silly things in today's time. Consider upgrading your work factors based on the resources cost out in the market. Consider having a unique work factors for information you are trying to save or for for each different user as well. Password hashing suggestion longer is better than a shorter with a higher entropy. Keep using passwords keep auditing your passwords for its existence in any breaches. And finally, I'd like to conclude a huge thanks for giving me this opportunity to share my thoughts. My DMs are always open for any interesting conversations. I blog a lot about these things in much more detail than what a 45 minute slot is going to ever allow me to. And finally, you will find all this algorithms implemented in Java, as well as the tuning tool on my GitHub repo. Thank you. Thank you. That was talk how to store sensitive information in 2020 and do stones and how to use a crypto building blocks using Java. Thank you again to Monsi. We have them right here for a live Q&A. So please put your questions in the Discord CPV Q&A channel. So just to start off, what's the reason for high memory switch is a requirement for KDFs. This is from Discord, by the way, I understand it helps make implementing ASICs harder, but I don't understand why. Sure. So ASICs, in my opinion, really started coming into existence because of the underlying bit mining philosophy is like increasing the computation over and over again, much, much faster. The hardware is still expensive and throwing memory at it will just make it much more expensive for a widespread adoption, actually. And that would ultimately add to the cost of cracking passwords offline, in my opinion. Again, we have not seen the future. We don't know what quantum is going to get us, but for foreseeable future for whatever the current theoretical crypto analysis says, that's what it is. Awesome. We have another question. When memory is the bottleneck, is there still an advantage to using ASICs or does it revert to only negligible gain over general purpose CPUs? Well, we still have a huge iteration factor, right? So it's a combination of both. So a general purpose CPU can't be that highly parallelized with the amount of memory required for each thread. So, yeah. Another question that we have is, does a salt need to be just unique instead of being that big to avoid having two passwords hash the same thing? This is in relation to 64 bits versus, say, 128 bits. Sure. Well, 64 bits is like the pure minimum requirement anyways from a standard, which was at least half, I mean, at least five or six years ago. I don't remember right now. Actually, one more. This is PBKDF probably. So, I mean, a little bit more salt 128 is not unacceptable. It's not going to add hugely to the processing power. Yeah, it's not a hard requirement. Even a CSPRNG is like maybe a little too much crypto kind of a situation. So yeah, it's it's a little bit on a higher side, but that's okay in my opinion. It does not add to the computation at all. Awesome. Another question we have, and there were some side parts of this, of course, and chat if you want to go further into them as I saw. But the question was, any thoughts on using Libsodium, the fork, instead of NACL, I have had great experiences with it. Yeah, the Libsodium is great. It is being adopted much more widely as I stood corrected NACL is last made then like, at least five, six years ago. I have a slight preference for NACL just because I like the documentation and the names of the APIs and the way the ease with which they are taking away all the back all the, like, more options to give the high the higher the chances of it actually going wrong so that way I feel NACL is slightly better but Libsodium is absolutely great anyways. So that's my personal preference but yeah. Awesome. Does anyone have any other Q&A questions, please drop them into the discord now. This is in the CPV talk Q&A text channel. And we just wait for a little bit. Also, thank you so much for your talks. These are really lovely and I'm really excited for the next one to be replayed again soon. Thank you. I'm having a lot of fun watching me talk for two hours. Oh, man, that's a lot of anxiety for me at least. Oh, that's fun. I think we have someone typing. Oh, just people love your talk. Thank you. Let's see. Let's see if this last person has a question. Thank you again Moncy for all of your time with us. We hope you take care. Enjoy the rest of Crypto Village and Defcon. We will love to see you in our discord soon. Yep. Please stay safe everyone. Please stay safe. Thank you. Bye.