WEBVTT

00:02.470 --> 00:10.170
Good afternoon, good evening, or even good morning, depending on which part of the world you are listening to this talk from.

00:10.410 --> 00:11.770
And no, it does not get old.

00:11.770 --> 00:19.670
I still want to give a huge shout-out to the CryptoVillage organizing community for making this virtual con happen for us.

00:21.010 --> 00:24.470
Welcome to the second talk of the day from my side.

00:25.270 --> 00:39.970
In this talk, I'm going to touch base upon how to store sensitive information securely so that we can safeguard it reasonably well against any kinds of offline cracking attempts.

00:40.270 --> 00:43.550
Before we go ahead, I'd like to introduce myself.

00:43.550 --> 00:44.990
I'm Manasi Sheth.

00:44.990 --> 00:51.810
I work as a security researcher at a leading static analysis company called Veracode.

00:52.710 --> 01:09.330
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.

01:10.330 --> 01:12.310
I'm a huge crypto enthusiast.

01:12.310 --> 01:23.350
I have spent a lot of time, or actually a reasonable amount of time, understanding different base crypto blocks.

01:24.350 --> 01:30.130
Its practical implementations, how it can be used in the real world.

01:30.170 --> 01:32.870
I understand a lot of anti-patterns.

01:32.870 --> 01:50.730
I've spent a lot of time looking at different crypto implementations across programming languages, and I try to translate all this expertise into making sure our customers' codebases are safe and to help pick up any anti-patterns.

01:53.510 --> 02:00.270
Recently, I got thinking, why are we seeing so many data breaches in the first place?

02:00.910 --> 02:06.250
Eventually, I realized, okay, this is going to be a matter of when rather than if.

02:06.250 --> 02:14.510
So, what can we do to protect this information once it is already breached, mainly from any kind of offline cracking?

02:14.510 --> 02:21.150
How can we make the information cracking process very, very expensive that it is almost useless?

02:21.150 --> 02:36.870
So, in that quest, first place I'll definitely go for that matter of which first thing comes to anyone's mind would be Troy Hunt's most organized, most informative site about this called Have I Been Pwned.

02:38.170 --> 02:54.150
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.

02:54.610 --> 03:12.870
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.

03:14.270 --> 03:17.950
So, this is what my analysis says.

03:17.950 --> 03:42.550
There were around 453 unique domains, 13% were storing it in plain text, 20% as hashes without any salting, 30% as salted hash, around 15% still using key derivative functions, which is a great step, and roughly 23% decided not to disclose, which in my opinion is plain text,

03:42.550 --> 03:44.990
but no judgments here.

03:46.350 --> 03:53.010
So, looking at it, I was thinking, okay, why were they breached in the first place?

03:53.150 --> 04:02.110
Most of the times it was because they did not pay a lot of attention in other kinds of security issues in their applications.

04:02.190 --> 04:08.350
A lot of them were simple SQL injections where entire databases were dumped out.

04:08.750 --> 04:12.270
Open S3 buckets was not an uncommon thing I saw.

04:12.270 --> 04:18.770
There were a lot of unprotected endpoints, which kind of leaked this data.

04:20.630 --> 04:24.770
So, that was my first lesson learned, that why are these things happening?

04:26.790 --> 04:40.810
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 even for innocent reasons sometimes, when there is nothing innocent about security.

04:42.690 --> 04:45.430
So, my next thing was, okay, now what can...

04:45.430 --> 04:48.730
what happens after these breaches are done?

04:49.290 --> 04:58.230
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.

04:58.230 --> 05:07.510
All these modern GPUs with extremely high parallelization capabilities can crack these things in minutes and making the cost much more...

05:07.510 --> 05:13.950
making the password cost much cheaper for any kind of offline mechanisms.

05:14.810 --> 05:23.190
With the whole Bitcoin mining philosophy of cracking, there are so many ASICs...

05:23.190 --> 05:31.890
sorry, application-specific integrated circuits out there, which makes the cost of cracking much more cheaper.

05:32.970 --> 05:40.810
There are literally trillions of hashes happening within seconds and this can be easily mapped to any kind of crypto-perimeters.

05:41.230 --> 05:47.210
All these things are going to keep making password cracking much more cheaper with time.

05:48.170 --> 05:49.950
So, what should we do?

05:49.950 --> 05:55.990
Well, the need of the hour was always stretching this information out so that it takes...

05:55.990 --> 06:02.330
we have to throw a lot of computational resources like CPU and memory to compute each password.

06:02.710 --> 06:07.050
With that, we are going to increase the speed with which the passwords are being calculated.

06:07.070 --> 06:27.390
This will greatly increase the offline cracking time and making us resilient towards any kind of modern computer architectures or brute-forcing or any kind of time-memory trade-off attacks or rainbow tables, dictionary attacks, all those kind of things.

06:28.010 --> 06:30.410
So, that's what we really needed.

06:31.030 --> 06:33.470
And how did we achieve that?

06:34.470 --> 06:37.950
Using key derivation functions.

06:37.950 --> 06:45.570
Well, this concept of key derivation function isn't specific to password hashing or secret information hashing.

06:45.570 --> 06:53.370
In fact, it came into existence for actually creating key material out of low-entropy inputs.

06:54.310 --> 07:08.680
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.

07:08.680 --> 07:12.000
It can be much better safeguarded at that time.

07:13.500 --> 07:20.980
And thus, this whole philosophy of using key derivation functions, KDFs, came into picture.

07:21.160 --> 07:23.740
So, simply how this works?

07:24.360 --> 07:35.740
Well, underlying, there is still an algorithm which is used, which is iterated hundreds and thousands and sometimes a couple of millions of times on a basic crypto-primitive.

07:36.060 --> 07:39.980
This type of functions are called adaptive functions.

07:41.040 --> 07:53.880
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.

07:53.880 --> 08:08.160
And still, it takes password and salt, gives out a fixed length hash, and it's the work factor which can be tuned based on different hardware your application is being deployed.

08:09.540 --> 08:18.100
So, that's going to be the base of our talk today to protect our safeguard against most of the offline cracking mechanisms.

08:20.220 --> 08:35.280
Some design considerations I'd like to point out here is try to save your password hash and salt in completely different databases, or a distributed database, or maybe a database and a property file or something.

08:35.280 --> 08:37.560
They should not be close to each other.

08:39.200 --> 08:43.420
Obviously, you're not going to store a password in plain text anymore.

08:44.620 --> 09:02.040
I can even go as far as saying that maybe we can have different work factors for different information we are trying to safeguard, or even different logins can have different work factors and storing work factor per login, obviously.

09:04.820 --> 09:19.080
With increasing cost in memory or CPU, it should be routinely checked that work factors are incremented accordingly to keep making password offline cracking expensive.

09:20.160 --> 09:25.480
Lastly, how expensive is tolerable or acceptable?

09:25.780 --> 09:34.740
Industry standards are any kind of interactive login, a latency of around one second is very acceptable.

09:34.740 --> 09:42.200
So make sure you tune your work factors in a way that the output is calculated around a second.

09:42.200 --> 09:49.720
This is acceptable latency, and it still increases the offline cracking time by a huge margin.

09:50.500 --> 10:07.760
And lastly, if you are using your password or 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 five to six seconds is quite acceptable in that scenario.

10:08.000 --> 10:14.700
So those are the things I'd like to say about key derivation functions in general.

10:16.420 --> 10:25.400
Let's start talking about different key derivation functions in existence, starting with adaptive functions.

10:25.880 --> 10:31.860
One of the oldest and the most widely adopted function was pbkdf2.

10:31.860 --> 10:38.540
Again, it came into picture because they really needed to generate keying materials.

10:39.080 --> 10:53.240
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.

10:53.240 --> 11:04.200
This function is also used as different crypto-primitive blocks for other modern functions these days.

11:05.640 --> 11:08.360
Let's see how this actually works internally.

11:08.840 --> 11:16.720
So just like our generic KDF working, it still takes a password, a salt, gives out a password hash.

11:16.720 --> 11:20.540
You can actually configure the size you expect out of a password hash.

11:20.540 --> 11:28.920
This feature was more for... because there is always requirement of a fixed key size for any kind of block cipher being used for.

11:29.780 --> 11:33.660
The work factor is in terms of iteration count.

11:36.620 --> 11:40.200
Let's talk a little bit about the internal working of this algorithm.

11:40.620 --> 11:48.800
What it does is it runs the crypto-primitive it iterates over is a pseudo-random function, usually a HMAC.

11:49.900 --> 12:02.600
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.

12:02.600 --> 12:06.180
Output is concatenated and that's your password hash.

12:07.840 --> 12:11.960
So you will see things a little bit in green color here.

12:11.960 --> 12:31.820
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 in roughly 1 second for interactive logins and roughly 5 seconds for any kind of non-interactive logins.

12:31.880 --> 12:41.480
So since PBKDF is government approved, they say the iteration count or the work factor for this algorithm should be around 10,000, which is way lower.

12:41.480 --> 12:42.620
Please don't do that.

12:42.620 --> 12:44.340
Please increase something.

12:44.380 --> 13:01.060
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.

13:01.140 --> 13:09.740
I ran this tool and the number of iterations were around 1.5 million for just 1 second of password calculation.

13:09.740 --> 13:13.580
Just imagine how off the government standards are here.

13:13.660 --> 13:19.980
So I'll highly motivate whichever algorithm you decide to use among all the algorithms you are going to talk about.

13:19.980 --> 13:23.320
Please run some kind of a tuning utility.

13:23.320 --> 13:25.040
Play around with your parameters.

13:25.040 --> 13:27.340
I'll be open sourcing this tool anyways.

13:27.340 --> 13:34.840
You can feel free to grab it and run it on your deployment hardware to tune your work factors accordingly.

13:37.200 --> 13:50.140
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 are using.

13:50.140 --> 13:57.520
The reason being it unnecessarily takes a lot of processing power for a no value add.

13:57.520 --> 13:59.980
So that's one of my suggestions.

14:00.200 --> 14:06.800
In this algorithm, you can just configure the CPU time involved.

14:06.800 --> 14:08.760
There is no memory involved.

14:08.760 --> 14:20.200
It is still not at all resilient towards any kinds of brute forcing attempts because of the highly parallelized nature of very cheaply rentable GPUs in today's time.

14:20.440 --> 14:25.240
If you don't have to comply with the government standards, please move on.

14:29.380 --> 14:36.900
Next, a notable mention, Bcrypt is very commonly used.

14:36.900 --> 14:44.640
It is based on a already deprecated symmetric cipher called Blowfish.

14:45.540 --> 14:49.800
It involves a little bit of memory for its internal working.

14:49.800 --> 14:52.500
So that's what is slightly better than pbkdf.

14:52.500 --> 14:59.820
But again, that memory or amount of memory it will need to use is not tunable by the user.

15:00.000 --> 15:08.400
And again, it was designed for generating key materials and not with storing secrets or password hashing in mind.

15:08.420 --> 15:10.840
So how does this algorithm work internally?

15:10.840 --> 15:17.620
Again, we have a password, a fixed size salt, a password output as a password hash.

15:18.800 --> 15:23.640
Iteration count is specified in logarithmic way.

15:23.640 --> 15:27.380
So this is going to be 2 raised to 14 number of iterations.

15:27.540 --> 15:30.760
And internally, how it works is it has this very expensive

15:33.980 --> 15:38.820
BlowCypher key setup process which involves some memory.

15:38.820 --> 15:54.260
So it iterates around that key setup and the output is again iterated through a normal BlowCypher Blowfish algorithm and the output is given to the caller.

15:56.760 --> 16:09.860
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 slightly more expensive than the previous one.

16:10.660 --> 16:15.760
And I don't understand why to use bcrypt, though I've seen a lot of usages of that.

16:15.800 --> 16:25.440
If you don't have to even comply by the government standards, why not use the more modern memory-hard functions.

16:25.800 --> 16:31.100
Okay, let's start talking about a few different memory-hard functions.

16:31.640 --> 16:34.520
The first one being sCrypt.

16:34.520 --> 16:41.260
It's one of the very earlier generation memory-hardness built inside the function.

16:42.260 --> 16:49.400
It is having an increased adaptation in cryptocurrencies mainly due to the nature of it.

16:49.400 --> 17:05.800
In cryptocurrencies, they don't really need to worry about time-memory trade-off attacks like offline cracking needs to and cryptocurrencies need to be more worried about side-channel attacks, which is not the domain for offline cracking.

17:05.980 --> 17:11.000
So it's mainly due to the nature of the applications it's widely adopted in cryptocurrencies.

17:11.000 --> 17:18.100
It's not like it's better or less secure for other applications.

17:19.220 --> 17:30.160
It was still designed for keying material, but it saw a lot of promising breakthroughs in being used for offline cracking.

17:31.560 --> 17:33.760
Okay, let's see how this works.

17:33.760 --> 17:38.240
It still has password salt output password we are given.

17:38.240 --> 17:42.180
We can still configure the length we desire out of the output.

17:43.120 --> 17:49.340
And if you see, the work factor has increased from 1 to almost 3 at this point.

17:49.560 --> 18:00.760
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.

18:01.760 --> 18:02.980
There is parallelization.

18:02.980 --> 18:05.020
You can parallelize the computation.

18:05.360 --> 18:12.160
I would like to note here that not all implementations give this control to the user.

18:12.160 --> 18:16.900
They still do it the way it depends on the implementation.

18:18.480 --> 18:26.820
You would note that there is only one parameter which will control both the CPU resources as well as the memory involved.

18:26.980 --> 18:33.420
Basically, it does not differentiate between both the resources we can throw at this algorithm.

18:33.420 --> 18:43.540
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.

18:43.840 --> 18:46.760
And finally is the block size which is used internally.

18:47.020 --> 18:49.080
Most typical values are 8 or 16.

18:49.080 --> 18:50.940
It does not make a huge difference.

18:53.300 --> 18:56.820
Let's talk a little bit about how the algorithm works internally.

18:57.020 --> 19:15.720
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.

19:17.040 --> 19:24.760
And again, the output is made of fixed size by PBKDFing it again and the output is passed to the caller.

19:26.840 --> 19:40.520
If you are choosing this, any kind of brute forcing attempts by a huge margin compared to adaptive functions.

19:40.820 --> 19:51.380
But the way the memory is being used by the algorithm internally, it is still using adjacent memory arrays in the consecutive operations.

19:51.580 --> 19:59.380
What I am trying to say is depending on the value of the password, the consecutive arrays are chosen.

19:59.380 --> 20:07.300
So this is always going to be a predefined sequence of memory arrays based on the input password.

20:07.320 --> 20:13.640
And what this opens us is towards the side channel attacks.

20:15.380 --> 20:21.860
Again, as we spoke about earlier, there is no way we can tune the CPU and memories independently.

20:21.860 --> 20:35.920
And since there is a lot of crypto involved in this algorithm, we have HMAC, we have PBKDF, we have Salsa, StreamCyphers, we have Xoring, we again have PBKDF.

20:35.920 --> 20:50.620
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 sneak, basically.

20:51.360 --> 20:57.060
So these are the things you should think about if you decide to go with a script.

20:57.060 --> 21:00.320
Still a huge step ahead of the adaptive functions.

21:00.320 --> 21:08.060
It still reduces the offline cracking cost by a huge margin, almost like a quadruple based on the number of iterations.

21:08.960 --> 21:10.660
It's a great choice.

21:11.000 --> 21:14.240
Well, don't they say save the best algorithm for the last?

21:14.340 --> 21:16.260
And that's what Argon2 is.

21:17.780 --> 21:36.060
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.

21:36.780 --> 21:43.320
It wasn't like before that no one was thinking about how to safely store information.

21:43.320 --> 21:45.580
Well, the breaches were happening.

21:45.580 --> 22:09.320
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 long as they can from any kind of offline cracking mechanism.

22:11.140 --> 22:19.700
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.

22:19.700 --> 22:25.920
It's very resilient against any brute forcing or dictionary attack.

22:25.920 --> 22:32.740
It's very hard to just parallelize it and run computations and start cracking passwords in minutes.

22:33.620 --> 22:45.060
They were also very resilient about the modern computer architecture which started maturing, became much cheaper and they were very, very cognizant about it will keep getting cheaper with time.

22:45.140 --> 22:54.160
So it's obviously going to be very resilient against any application specific integrated circuit architectures or even FPGA arrays.

22:55.140 --> 23:03.720
A few years ago, there were limited implementations of this algorithm out of a direct cryptographic library.

23:03.720 --> 23:06.040
But that situation has greatly changed.

23:06.040 --> 23:09.460
So congratulations, you don't have to implement this algorithm yourself.

23:09.460 --> 23:25.500
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.

23:26.880 --> 23:29.160
So let's see how this algorithm works.

23:29.160 --> 23:31.440
Well, you still have your passwords and salts.

23:31.440 --> 23:35.000
You still will get a fixed length hashed password.

23:35.000 --> 23:39.440
In terms of memory factors, you have three parameters now.

23:39.520 --> 23:41.700
One is obviously parallelization.

23:41.700 --> 23:58.940
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.

23:58.940 --> 24:04.200
So it basically decouples both the resources resource utilizations.

24:04.200 --> 24:08.840
Very unlike sCrypt and one of the huge advantages.

24:09.940 --> 24:30.180
There is some crypto analysis done on Argon2 algorithms which makes any iterations below 10 a little susceptible but it is more theoretical crypto analysis so don't freak out but choose a parameter which is at least greater than 10 and that's the reason.

24:31.960 --> 24:36.380
Talking about modes of operation which is crucial.

24:36.540 --> 24:40.900
There are two main types of modes in this algorithm.

24:40.900 --> 24:56.340
One is data-dependent mode which is what was there in the previous sCrypt 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.

24:58.240 --> 25:06.300
How these modes work for that let's start talking about the internal crypto of this algorithm.

25:06.440 --> 25:14.980
So how it goes is it first computes a hash of password salt and all these different parameters .

25:14.980 --> 25:18.700
Any hash can be used usually it is Blake2.

25:19.620 --> 25:30.220
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.

25:30.220 --> 25:37.280
So just imagine it as rows and columns being populated iteratively for a number of iterations of times.

25:38.460 --> 25:44.320
So for data-dependent mode and data-independent mode how it is different?

25:44.320 --> 25:57.680
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.

25:57.680 --> 26:00.740
And for data-independent mode it is completely random.

26:00.960 --> 26:10.620
So basically what it comes down to is the sequence of memory array populations per iteration is actually based on the input password.

26:10.840 --> 26:28.240
And this particular feature of this algorithm makes it susceptible to side channel attacks which is okay for cryptocurrencies but not very comfortable for any kind of password storage.

26:28.240 --> 26:44.000
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 this kind of attacks might have.

26:44.520 --> 26:47.020
So some design considerations.

26:47.020 --> 26:56.300
You have to tune your parameters a little more carefully and mostly because you have few more parameters to take care of.

26:56.760 --> 27:13.420
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.

27:13.480 --> 27:15.800
And with that we get the best of both worlds.

27:15.800 --> 27:22.920
We are resilient towards side channel attacks as well as we are much better with the time memory trade-off issues.

27:23.580 --> 27:26.580
So that's what I would say.

27:26.580 --> 27:30.420
Use Argon2 mainly in 2ID mode.

27:30.480 --> 27:38.900
We already looked at what is the best parameter options for an output for password computation within a second.

27:40.840 --> 27:49.920
Since Argon2 is the algorithm I am highly recommending to be used for any kind of sensitive information storage.

27:50.220 --> 27:58.880
I'd like to quickly show how easy it is to just start using this by any implementations you have access to.

28:00.000 --> 28:04.520
Just to record this demo, I had a forked off EC2 instance.

28:04.520 --> 28:06.200
These are the details of the instance.

28:06.200 --> 28:13.520
It's a typical standard T2 medium with 2 CPUs and 4GB of RAM.

28:13.520 --> 28:17.680
Currently available as of this moment is around 2.8GB.

28:17.680 --> 28:22.400
It's using x86 architecture on a Linux kernel.

28:23.160 --> 28:28.400
So let's see how quick it is to start using this.

28:29.580 --> 28:38.540
Well, I am going to use NACL's password module where the Argon2 ID is being supported.

28:38.540 --> 28:48.780
Well, a quick pro tip whenever given a choice of any crypto implementation you need if you have a choice, always go for NACL.

28:48.780 --> 28:54.060
It's very cleanly written by cryptographers rather than actual developers.

28:54.420 --> 28:59.800
They deprecate things which are no more secure or better options are available out there.

28:59.800 --> 29:03.040
They quickly deprecate all those things from anyone's view.

29:03.040 --> 29:07.280
So chances of making wrong choices are eliminated.

29:08.440 --> 29:16.160
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.

29:16.280 --> 29:20.660
Start time is going to be current time.

29:20.760 --> 29:23.940
Let's start storing the password.

29:27.360 --> 29:30.900
First, let's use the module

29:33.980 --> 29:37.440
hash.argon2id Why not use the hybrid one?

29:37.440 --> 29:39.260
Best of both worlds, right?

29:39.880 --> 29:42.920
And the string output for that.

29:43.020 --> 29:45.040
Giving the password

29:49.450 --> 29:53.710
long is better than higher, entropy shorter one.

29:53.710 --> 29:55.810
So that's what I choose for.

29:56.350 --> 30:00.350
Ops limit is the number of iterations around the memory array.

30:00.350 --> 30:07.190
Let's go for 14 till 10 is already theoretically crypto-analyzed.

30:07.190 --> 30:09.810
So anything about 10 is great.

30:11.670 --> 30:13.950
And the key thing, memory.

30:14.530 --> 30:16.910
It's again logarithmically given.

30:17.330 --> 30:20.530
We already know the answer from our tuning tool.

30:20.750 --> 30:21.710
So let's see.

30:21.710 --> 30:26.190
This is as short and sweet as it can get actually.

30:26.570 --> 30:31.630
And just to keep track of time, let's see how much it is.

30:32.350 --> 30:35.750
And hopefully this compiles and runs actually.

30:36.850 --> 30:40.990
Okay, so it took around 1.1 second.

30:41.990 --> 30:43.990
Can we go any higher?

30:43.990 --> 30:45.510
Let's see.

30:45.550 --> 30:56.910
Going from 27 to 28 which is 2.3 I'll leave that choice to you at this point.

30:56.910 --> 31:00.870
This is how we should typically tune any parameters.

31:06.210 --> 31:12.050
It's almost second nature to wonder how these functions actually compare against each other.

31:12.610 --> 31:32.990
There is not a lot of research done in this topic about how to actually put a dollar value or number of years of cracking a particular breach mechanism or There is no apples to oranges comparison as well you could imagine.

31:33.210 --> 31:38.230
But good notable work is being done by these two papers.

31:38.230 --> 31:47.510
One released in USENIX a couple of years ago and another one done in conjunction between Microsoft and Purdue University.

31:48.030 --> 31:58.970
In the most trivial way, what they do is they look at the latest hardware and the memory cost and just start calculations from there.

31:59.930 --> 32:03.320
And that's what I tried to do it as of yesterday.

32:04.370 --> 32:14.790
So for adaptive functions it's just going to be again a huge list of disclaimers here before I actually talk about this very very cautiously actually.

32:16.250 --> 32:24.710
I'm assuming the keyword, the password the sort, the output all those things are same across all these functions.

32:24.870 --> 32:28.430
I'm also assuming there is no electricity cost involved.

32:31.590 --> 32:39.770
Talking about these figures for adaptive functions it's just going to be as simple as number of iterations per cost of hardware.

32:39.990 --> 32:51.210
And the cost of hardware is much easier to calculate these days because most of the modern A6 hardwares for Bitcoin mining come with that statistics.

32:51.210 --> 33:10.390
So looking at one of the most leading hardware in that department coming from Antminer one of the best configured one is around $2500 and it promises to do 110 trillion hashes per second.

33:10.530 --> 33:14.310
And trillion is 10 raised to 12 if you are wondering as I was.

33:15.470 --> 33:23.510
So using that configuration with the number of iterations adaptive function is going to take so much time.

33:23.510 --> 33:36.050
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.

33:36.890 --> 33:53.710
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 mode where the array used for memory calculations is based on the input passwords.

33:54.070 --> 34:10.750
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 quadruples in memory hardness is going to be much more expensive compared to adaptive functions.

34:10.750 --> 34:13.090
And this is just for data dependent mode.

34:13.090 --> 34:20.370
For data independent mode well the cost might still be the same but the number of guesses is going to be exponential.

34:20.710 --> 34:27.830
So this is just sharing some statistics still in a more conservative tone.

34:29.850 --> 34:40.670
This is all what I wanted to speak about today around offline cracking different mechanisms we can use to safeguard ourselves.

34:40.950 --> 34:44.090
Key derivation function being the key of that.

34:44.170 --> 34:53.970
How to tune different parameters and what kind of design concentrations you should be doing while picking each one of that.

34:55.190 --> 35:04.610
Next I'd like to talk about a little bit about how all this information can be mapped to storing any kind of secrets you need to.

35:04.630 --> 35:11.510
For that you need to sit down and do a little bit of threat modeling for your own usages.

35:11.510 --> 35:15.650
Something like what is sensitive to your business?

35:15.650 --> 35:19.370
Do you need to comply with any GDPR requirements?

35:19.370 --> 35:23.310
Are you storing any personally identified information?

35:24.130 --> 35:32.710
Can it be used for crafting further attacks against the users whose information might be breached?

35:34.070 --> 35:36.270
How are you storing that information?

35:36.270 --> 35:37.550
Are you storing it in a database?

35:37.550 --> 35:39.730
Which fields are involved in that database?

35:39.730 --> 35:49.470
All those things need to be thought about and you can easily map all these KDFs to work for your own needs.

35:50.550 --> 36:07.690
Lastly, you must have come across countless suggestions and password hygiene requirements or tips over years since it is such a key aspect of any kind of authentication mechanism .

36:08.610 --> 36:14.310
Just for the completeness of this talk, I'd like to say a few things about it.

36:14.310 --> 36:16.750
Always choose a unique password.

36:16.910 --> 36:18.770
Password managers are great.

36:18.770 --> 36:20.670
Please use those.

36:20.850 --> 36:26.250
Longer passwords are better than shorter, higher entropy ones.

36:27.370 --> 36:29.410
This is what I typically do.

36:29.410 --> 36:33.490
I store my passwords in a password manager.

36:33.490 --> 36:36.810
This is the configuration I use while generating any new password.

36:36.810 --> 36:41.370
I choose a longer password and with a reasonable amount of entropy.

36:41.630 --> 36:54.740
The point I'm trying to make is there is a lot of crypto analysis done which points us towards the theory that longer passwords are better than shorter ones with higher entropy.

36:54.740 --> 37:11.920
A password whose length is 25 or 30 characters is far better than a password which is of 8 or 10 characters standard length with two special characters, one uppercase and two digits and those kind of things.

37:12.500 --> 37:13.840
So do that.

37:13.840 --> 37:25.180
The website we looked at about the data breached information, they have a nice API exposed by again Troy Hunt.

37:25.940 --> 37:43.940
It would be great to use that API in your websites or even password managers can start using that where if a password which has already been seen in a breach is being used, then they would be flagged and that would go a long way.

37:43.940 --> 37:50.920
Finally, in conclusion, please embrace adaptive key derivation functions.

37:50.920 --> 37:58.220
Use memory hard functions based on your choice and comfort level with the amount of crypto analysis done.

37:58.220 --> 38:03.160
Please don't do plain text or hashing or your own DIY designs.

38:03.160 --> 38:06.340
Those are all silly things in today's time.

38:06.420 --> 38:13.840
Consider upgrading your work factors based on the resources cost out in the market.

38:17.420 --> 38:27.860
Consider having unique work factors for information you are trying to save or for each different user as well.

38:28.200 --> 38:33.260
Password hashing suggestion longer is better than shorter with a higher entropy.

38:33.260 --> 38:34.600
Keep using passwords.

38:34.600 --> 38:39.820
Keep auditing your passwords for its existence in any breaches.

38:40.540 --> 38:49.080
And finally, I would like to conclude a huge thanks for giving me this opportunity to share my thoughts.

38:49.080 --> 38:53.340
My DMs are always open for any interesting conversations.

38:53.340 --> 39:01.780
I blog a lot about these things in much more detail than what a 45 -minute slot is going to ever allow me to.

39:01.860 --> 39:12.220
And finally, you will find all these algorithms implemented in Java as well as the tuning tool on my GitHub repo.

39:12.340 --> 39:13.580
Thank you.

39:41.370 --> 39:48.490
That was talk how to store sensitive information in 2020 and do's, don'ts, and how-tos of cryptobuilding blocks used in Java.

39:48.490 --> 39:50.590
Thank you again to Mansi.

39:50.690 --> 39:56.830
We have them right here for a live Q&A, so please put your questions in the Discord CPB Q&A channel.

39:58.750 --> 40:05.670
So just to start off, what's the reason for high memory usage is a requirement for KDFs?

40:05.670 --> 40:07.290
This is from Discord, by the way.

40:07.290 --> 40:11.870
I understand it helps make implementing ASICs harder, but I don't understand why.

40:12.810 --> 40:14.030
Sure.

40:14.110 --> 40:27.570
So ASICs, in my opinion, really started coming into existence because of the underlying bit mining philosophy is increasing the computation over and over again much, much faster.

40:28.010 --> 40:39.930
The hardware is still expensive and throwing memory at it will just make it much more expensive for a widespread adoption, actually.

40:40.190 --> 40:46.430
And that would ultimately add to the cost of cracking passwords offline, in my opinion.

40:47.090 --> 40:48.930
Again, we have not seen the future.

40:48.930 --> 40:59.090
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.

40:59.810 --> 41:00.670
Awesome.

41:00.850 --> 41:02.570
We have another question.

41:03.110 --> 41:11.330
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?

41:12.190 --> 41:15.370
Well, we still have a huge iteration factor, right?

41:15.370 --> 41:17.210
So it's a combination of both.

41:17.210 --> 41:24.370
So a general-purpose CPU can't be that highly paralyzed with the amount of memory required for each thread.

41:24.710 --> 41:25.630
So, yeah.

41:27.290 --> 41:27.890
Cool.

41:28.130 --> 41:36.930
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?

41:36.930 --> 41:40.410
This is in relation to 64 bits versus, say, 128 bits.

41:40.730 --> 41:41.690
Sure.

41:42.050 --> 41:51.530
Well, 64 bits is, like, the pure minimum requirement anyways from a standard which was written, like, at least half a dozen... I mean, at least five or six years ago.

41:51.530 --> 41:53.550
I don't remember right now.

41:53.550 --> 41:54.270
Actually, even more.

41:54.270 --> 41:56.090
This is PBKDF, probably.

41:56.750 --> 41:59.390
So , I mean, a little bit more salt.

41:59.390 --> 42:01.070
128 is not unacceptable.

42:01.070 --> 42:04.670
It's not going to add hugely to the processing power.

42:04.930 --> 42:06.870
Yeah, it's not a hard requirement.

42:06.870 --> 42:12.610
Even CSPRNG is, like, maybe a little too much crypto kind of a situation.

42:13.230 --> 42:13.950
So, yeah.

42:14.050 --> 42:17.530
It's a little bit on the higher side, but that's okay, in my opinion.

42:17.530 --> 42:20.790
It does not add to the computation at all.

42:21.710 --> 42:22.410
Awesome.

42:23.010 --> 42:29.130
Another question we have, and there were some side parts to this, of course, in chat if you want to go further into them, as I saw.

42:29.270 --> 42:34.130
But the question was, any thoughts on using Libsodium, the fork, instead of NACL?

42:34.130 --> 42:36.650
I have had great experiences with it.

42:37.750 --> 42:39.670
Yeah, Libsodium is great.

42:39.670 --> 42:43.270
It is being adopted much more widely, as I stood corrected.

42:43.350 --> 42:48.070
NACL is last made at least five, six years ago.

42:48.470 --> 43:03.670
I have a slight preference for NACL just because I like the documentation and the names of the APIs and the ease with which they are taking away all the more options you give, the higher the chances of it actually going wrong.

43:03.670 --> 43:06.530
So that way I feel NACL is slightly better.

43:06.530 --> 43:09.070
But Libsodium is absolutely great anyways.

43:09.490 --> 43:11.550
So that's my personal preference.

43:12.510 --> 43:13.390
Awesome.

43:14.270 --> 43:17.010
Does anyone have any other Q&A questions?

43:17.010 --> 43:19.330
Please drop them into the Discord now.

43:21.930 --> 43:25.650
This is in the CPB Talk Q&A text channel.

43:35.030 --> 43:36.610
And we just wait for a little bit.

43:36.610 --> 43:38.390
Also, thank you so much for your talks.

43:38.390 --> 43:43.130
These are really lovely, and I'm really excited for the next one to be replayed again soon.

43:43.130 --> 43:44.870
Thank you.

43:46.110 --> 43:49.870
I'm having a lot of fun watching me talk for two hours.

43:49.870 --> 43:55.950
Oh , man, that's a lot of anxiety for me at least.

43:56.690 --> 43:57.890
That's fun.

44:01.080 --> 44:03.240
I think we have someone typing.

44:03.240 --> 44:05.840
Oh, no, just people love your talk.

44:06.200 --> 44:07.080
Thank you.

44:07.200 --> 44:10.180
Let's see if this last person has a question.

44:17.030 --> 44:17.810
All right.

44:18.370 --> 44:21.390
Thank you again, Mansi, for all your time with us.

44:21.410 --> 44:22.610
We hope you take care.

44:22.610 --> 44:24.910
Enjoy the rest of Crypto Village and DEF CON.

44:25.150 --> 44:28.830
We will love to see you in our Discord soon.

44:29.990 --> 44:31.490
Please stay safe, everyone.

44:31.490 --> 44:32.550
Please stay safe.

44:32.650 --> 44:33.430
Thank you.

44:33.430 --> 44:34.270
Bye-bye.

