0:00:16.540,0:00:18.560 TONY ARCIERI: We ready to go here? 0:00:19.700,0:00:21.160 So it used to be you didn't have to 0:00:21.169,0:00:24.509 think about security when you're writing a[br]Ruby program. 0:00:24.509,0:00:28.210 Well, guess what, pall? Times have changed![br]There's all 0:00:28.210,0:00:30.579 sorts of bad people out there, and you gotta 0:00:30.579,0:00:32.719 know how to stop them! 0:00:32.719,0:00:37.600 All right. I'm not gonna do the entire talk 0:00:37.600,0:00:40.239 as Crocket impressions. Sorry. 0:00:40.239,0:00:43.539 So I am Tony Arcieri, or @bascule on Twitter. 0:00:43.539,0:00:46.949 I work on the, or work at the inform- 0:00:46.949,0:00:50.719 I work at Square on the information security[br]team. 0:00:50.719,0:00:54.980 And my talk today is about cryptography and,[br]you 0:00:54.980,0:00:58.039 know, I just want to encrypt something. How[br]hard 0:00:58.039,0:01:00.809 could it possibly be? 0:01:00.809,0:01:04.580 The answer to this is definitely hard. So[br]how 0:01:04.580,0:01:07.140 hard is it? Well, today you're gonna drink[br]from 0:01:07.140,0:01:11.210 the fire hose, and I'm gonna show you exactly 0:01:11.210,0:01:12.480 how hard it is. 0:01:12.480,0:01:17.760 So quick itinerary here. We're gonna talk[br]about attacks. 0:01:17.760,0:01:19.880 We're going to talk about how to defeat them 0:01:19.880,0:01:24.510 using something called authenticated encryption.[br]And then we're going 0:01:24.510,0:01:27.290 to learn how to completely avoid all these[br]problems 0:01:27.290,0:01:30.720 by just letting cryptographers do all this[br]stuff for 0:01:30.720,0:01:31.280 us. 0:01:31.280,0:01:35.130 So, I think Ruby's traditionally been in a[br]pretty 0:01:35.130,0:01:38.440 bad situation when it comes to cryptography,[br]and the 0:01:38.440,0:01:41.690 main reason for this is the OpenSSL library[br]has 0:01:41.690,0:01:43.910 been the only game in town for quite some 0:01:43.910,0:01:44.920 time. 0:01:44.920,0:01:48.610 So I think we can change this. I think 0:01:48.610,0:01:52.450 this is a fixable problem. But to do that, 0:01:52.450,0:01:54.960 we really need to know, how the hell does 0:01:54.960,0:01:57.090 crypto actually work? 0:01:57.090,0:02:01.790 So, the answer to this is magic. But, not 0:02:01.790,0:02:06.670 really magic. It's actually just math. So[br]there's two 0:02:06.670,0:02:10.580 types of encryption cyphers I'm gonna talk[br]about today. 0:02:10.580,0:02:13.560 We'll show how one builds on the other. The 0:02:13.560,0:02:16.200 first is called Symmetric. So here we have[br]Alice 0:02:16.200,0:02:18.850 who just wants to send a message to herself, 0:02:18.850,0:02:22.670 or rather, just put this message away in a 0:02:22.670,0:02:25.790 box and lock it, and then she can use 0:02:25.790,0:02:28.140 the key to open it again and get the 0:02:28.140,0:02:30.100 original message out. 0:02:30.100,0:02:32.700 The other is asymmetric. So Alice wants to[br]send 0:02:32.700,0:02:35.680 a message to Bob. Same idea here. She's gonna 0:02:35.680,0:02:37.450 put it in a box and lock it with 0:02:37.450,0:02:40.250 one key, and then Bob magically has another[br]key 0:02:40.250,0:02:43.530 that lets him get the message out. 0:02:43.530,0:02:46.680 The big problem with encryption is it lies[br]at 0:02:46.680,0:02:52.650 the intersection of math and security. So,[br]like, math 0:02:52.650,0:02:55.300 is hard and security is hard, and when we 0:02:55.300,0:02:58.350 put all these things together, especially[br]when we're talking 0:02:58.350,0:03:01.209 about doing this in a programming language[br]where we 0:03:01.209,0:03:05.480 have bugs, things are gonna get pretty hard. 0:03:05.480,0:03:08.060 And this is one of my favorite quotes from 0:03:08.060,0:03:12.100 Cryptonomicon. So, this is kind of the situation[br]we're 0:03:12.100,0:03:14.170 in, I think, in the Ruby world. That most 0:03:14.170,0:03:17.680 of the encryption gems out there aren't designed[br]by 0:03:17.680,0:03:23.420 cryptographers, they're designed by amateurish[br]people who are trying 0:03:23.420,0:03:26.280 to, trying to put everything together but[br]maybe just 0:03:26.280,0:03:28.660 don't quite know how. 0:03:28.660,0:03:31.730 So I'm gonna go through all the attacks on 0:03:31.730,0:03:35.060 symmetric crypto. Unfortunately, I don't think[br]I have time 0:03:35.060,0:03:37.750 to do asymmetric crypto. So I left a bunch 0:03:37.750,0:03:40.819 of those attacks out. But, guess what, it's[br]even 0:03:40.819,0:03:46.130 worse. So we're gonna talk about AES today.[br]AES 0:03:46.130,0:03:50.450 is a symmetric encryption cipher. It's great.[br]I would 0:03:50.450,0:03:53.650 recommend you use AES, but it's sort of like 0:03:53.650,0:03:57.250 aim away from face, read all instructions[br]before proceeding 0:03:57.250,0:03:58.670 kind of thing. 0:03:58.670,0:04:02.680 So this is how AES works. It's a block 0:04:02.680,0:04:05.920 cypher, so it works on fix-sized blocks. So[br]we're 0:04:05.920,0:04:10.069 gonna take a sixteen byte piece of plain text 0:04:10.069,0:04:11.810 and we're gonna use a key, which can either 0:04:11.810,0:04:15.540 be sixteen, twenty-four, or thirty-two bytes.[br]You want to 0:04:15.540,0:04:16.659 generate that randomly. 0:04:16.659,0:04:19.899 And from that we're gonna get a sixteen byte 0:04:19.899,0:04:21.069 block of cyphertext. 0:04:21.069,0:04:24.699 So, that's all well good. AES works great.[br]There's 0:04:24.699,0:04:27.889 just this little problem. How do we encrypt[br]something 0:04:27.889,0:04:30.169 that is large than sixteen bytes? 0:04:30.169,0:04:35.330 Well, one solution to this, PHP decided to[br]use 0:04:35.330,0:04:38.830 a different ver- so AES is derived from a 0:04:38.830,0:04:43.240 cypher called Rijndael. PHP should be the[br]version of 0:04:43.240,0:04:47.520 Rijndael with the 256 byte block size. So[br]this 0:04:47.520,0:04:52.139 is awesome. It's a completely non-standard[br]version of AES 0:04:52.139,0:04:55.279 that only PHP uses. 0:04:55.279,0:04:58.150 So let's not do that. 0:04:58.150,0:05:01.219 So let's figure out how to do this, right. 0:05:01.219,0:05:03.199 So the naive solution to this is to use 0:05:03.199,0:05:08.180 something called ECB mode. So there's this[br]guy here, 0:05:08.180,0:05:11.439 he apparently couldn't find out how to use,[br]do 0:05:11.439,0:05:14.979 encryption with OpenSSL itself, so he went[br]off and 0:05:14.979,0:05:19.059 he made his own gem to encrypt stuff with 0:05:19.059,0:05:20.379 ECB mode. 0:05:20.379,0:05:23.800 You see there, he has C security nodes, ECB 0:05:23.800,0:05:27.249 mode only. The problem with the ECB mode is 0:05:27.249,0:05:32.020 it's really, really bad. So what ECB mode[br]would 0:05:32.020,0:05:34.639 have you to is just take all these blocks 0:05:34.639,0:05:37.699 of plain text and encrypt them under the same 0:05:37.699,0:05:39.919 key. 0:05:39.919,0:05:42.259 So what's the problem with that? Well, it[br]leaks 0:05:42.259,0:05:46.599 information. So let's say this is our plain[br]text 0:05:46.599,0:05:49.009 we want to encrypt. If we run that through 0:05:49.009,0:05:52.080 ECB mode, we get something that looks like[br]this. 0:05:52.080,0:05:54.150 So I think you can all see from this 0:05:54.150,0:05:59.039 that this thing isn't very well-encrypted.[br]We can totally, 0:05:59.039,0:06:02.199 can totally see what it is. 0:06:02.199,0:06:05.909 So what's the solution to this? So, we need 0:06:05.909,0:06:10.669 to use a different block cipher mode of operation. 0:06:10.669,0:06:13.110 There's lots of these guys. We just kind of 0:06:13.110,0:06:15.659 have to pick one. There's all sorts of various 0:06:15.659,0:06:20.469 trade-offs. The one that people mostly settled[br]on today 0:06:20.469,0:06:22.119 is countermode. 0:06:22.119,0:06:26.309 So counter mode is fairly easy to understand,[br]I 0:06:26.309,0:06:29.639 think. It's sort of similar to a one-time[br]pad. 0:06:29.639,0:06:32.469 So what we're gonna do is take a block 0:06:32.469,0:06:34.610 cypher, like AES and try to turn it into 0:06:34.610,0:06:38.599 a stream cypher. So what we're gonna do is 0:06:38.599,0:06:41.559 effectively generate a bunch of pseudo-random[br]numbers. 0:06:41.559,0:06:44.719 So we feed in a nance, which is some 0:06:44.719,0:06:48.559 secret starting place, and a key, which is[br]the 0:06:48.559,0:06:51.009 same as what we were putting in before. And 0:06:51.009,0:06:53.189 then there's this little counter, and every[br]time we 0:06:53.189,0:06:56.599 crypt a block, it's just gonna count it by 0:06:56.599,0:06:56.949 one. 0:06:56.949,0:06:58.899 So what we're actually gonna do is combine[br]the 0:06:58.899,0:07:01.809 nance and the counter, and encrypt that with[br]AES, 0:07:01.809,0:07:03.389 and what we're gonna get is a little bit 0:07:03.389,0:07:06.849 of pseudo-random pad for each part of the[br]plain 0:07:06.849,0:07:10.339 text. And for each of these paths, for each 0:07:10.339,0:07:12.409 of these blocks, we're gonna x over the pad 0:07:12.409,0:07:14.699 with a plain text, and that's gonna give us 0:07:14.699,0:07:15.770 our cypher text. 0:07:15.770,0:07:18.740 So if we go back to our little Ruby 0:07:18.740,0:07:23.449 gem image here, what we're gonna do is combine 0:07:23.449,0:07:26.059 this with a pseudo random pad, and what we're 0:07:26.059,0:07:29.809 gonna get is the cypher text. So I hope 0:07:29.809,0:07:34.499 you can see that little subtle change there.[br]So 0:07:34.499,0:07:37.039 this is actually encrypted, right. We can[br]no longer 0:07:37.039,0:07:42.360 see that gem and now we're done. Success! 0:07:42.360,0:07:47.949 We've, we've obtained confidentiality. Except[br]a problem. 0:07:47.949,0:07:50.839 Our repeating nonces will leak information.[br]So we can't 0:07:50.839,0:07:54.469 ever use the same nance and key. So the 0:07:54.469,0:07:57.379 solution is just don't do that. 0:07:57.379,0:08:02.259 So we've got another problem here. Support[br]for counter 0:08:02.259,0:08:06.689 mode in Ruby OpenSSL is spotty. So unfortunately[br]we 0:08:06.689,0:08:10.189 can't use sort of the industry best practices[br]here. 0:08:10.189,0:08:11.629 And what we're gonna use is CBC mode. CDC 0:08:11.629,0:08:15.860 mode is fine. There are a few small issues 0:08:15.860,0:08:19.889 with it, but unfortunately I don't have time[br]to 0:08:19.889,0:08:21.259 go into them. 0:08:21.259,0:08:24.389 So, next problem. Attacker, who we hand this[br]message 0:08:24.389,0:08:30.009 to, can manipulate, with something called[br]malleability. So let's 0:08:30.009,0:08:33.198 say our plain text is attack at dawn, and 0:08:33.198,0:08:35.068 we encrypt that and we have a cypher text 0:08:35.068,0:08:37.360 and we hand that to an attacker. Let's say 0:08:37.360,0:08:39.599 this attacker is able to guess what the plain 0:08:39.599,0:08:41.318 text was. 0:08:41.318,0:08:43.929 So what this attacker can then do is x 0:08:43.929,0:08:47.630 over part of the cypher text with what he 0:08:47.630,0:08:49.980 thinks the original plain text is, and then[br]x 0:08:49.980,0:08:52.029 over that again with what he wants it to 0:08:52.029,0:08:54.480 be. So what you get is sort of this 0:08:54.480,0:08:57.870 like manipulated cypher text, and now when[br]we decrypt 0:08:57.870,0:09:00.949 it, it gives us the wrong thing. This isn't 0:09:00.949,0:09:03.360 what we expected it to be. 0:09:03.360,0:09:05.740 So the solution to this is to use something 0:09:05.740,0:09:09.740 called a message authentication code. When[br]we combine this 0:09:09.740,0:09:12.740 with a encryption cypher, what we get is something 0:09:12.740,0:09:15.470 called authenticate encryption. 0:09:15.470,0:09:18.279 So with a Mac, what we do is we 0:09:18.279,0:09:22.339 take the message and then we have a key, 0:09:22.339,0:09:24.120 and when we combine the message and the key, 0:09:24.120,0:09:27.040 we get this fix-lengthed tag. So we know we 0:09:27.040,0:09:31.399 have the right message when we take the same 0:09:31.399,0:09:33.440 message and the same key and then we get 0:09:33.440,0:09:35.199 the mac we expect. 0:09:35.199,0:09:38.730 So once again, there's a whole lot of these. 0:09:38.730,0:09:42.339 Like, HMAC is the one I'm sure you've heard 0:09:42.339,0:09:44.680 of if you've heard of one of these. The 0:09:44.680,0:09:47.160 others are somewhat less common. 0:09:47.160,0:09:51.810 So now we have yet another problem. What order 0:09:51.810,0:09:56.560 do we combine the encryption and the mac?[br]So 0:09:56.560,0:10:00.870 there's effectively three ways to do this,[br]and common 0:10:00.870,0:10:03.560 internet tools have all sort of chosen their[br]own 0:10:03.560,0:10:07.810 different way. So the first is called mac-then-encrypt.[br]This 0:10:07.810,0:10:11.149 is what's used by SSL and TLS. So the 0:10:11.149,0:10:14.310 idea is you take the plain text and you 0:10:14.310,0:10:17.060 compute the mac to the plain text, and then 0:10:17.060,0:10:22.339 you sort of combine those together and encrypt[br]both. 0:10:22.339,0:10:25.000 Another way to do it is called encrypt-then-mac.[br]This 0:10:25.000,0:10:30.300 is used by the IP sect protocol for, like, 0:10:30.300,0:10:34.509 yeah. So we have plain text. What we're gonna 0:10:34.509,0:10:37.860 do is encrypt it first, and then we're going 0:10:37.860,0:10:42.379 to calculate the mac of the cypher text. So 0:10:42.379,0:10:45.190 the third way, which is used by SSH, we 0:10:45.190,0:10:49.190 take the plain text and we encrypt it, then 0:10:49.190,0:10:52.009 we get the cypher text, and then we take 0:10:52.009,0:10:54.000 the original plain text and we compute the[br]mac 0:10:54.000,0:10:56.149 of that and then we put the cypher text 0:10:56.149,0:10:58.519 and the mac of the plain text together. 0:10:58.519,0:11:03.029 So which, which of these sort of three standards 0:11:03.029,0:11:06.120 or three approaches got it right? Anybody[br]want to 0:11:06.120,0:11:10.170 take a guess which of these is actually the 0:11:10.170,0:11:11.740 right way? 0:11:11.740,0:11:13.910 None. There's actually a right answer. One[br]of them 0:11:13.910,0:11:18.040 did get it right. So the answer is encrypt-then-mac 0:11:18.040,0:11:21.430 used by IP sect. So why? What's wrong with 0:11:21.430,0:11:24.319 these other methods? 0:11:24.319,0:11:26.920 So SSL/TLS, you might remember there was this[br]attack 0:11:26.920,0:11:31.170 called Beast. It's using something called[br]a padding oracle. 0:11:31.170,0:11:34.430 I didn't really go into how padding actually[br]works, 0:11:34.430,0:11:37.529 but it's how you deal with, when your plain 0:11:37.529,0:11:40.370 text isn't actually aligned to a block. 0:11:40.370,0:11:42.730 So, using Beast, they were able to get a 0:11:42.730,0:11:46.459 little bit of information out of when it decrypts 0:11:46.459,0:11:50.259 and it does this padding check and you can 0:11:50.259,0:11:52.269 tell if it got through the padding or not 0:11:52.269,0:11:54.360 before it hit the mac. 0:11:54.360,0:11:57.160 So the solution TLS uses now is to make 0:11:57.160,0:11:59.160 sure it always checks the mac, even if the 0:11:59.160,0:12:01.569 padding fails. So that's a little bit of a 0:12:01.569,0:12:02.730 band aid. 0:12:02.730,0:12:07.660 Encrypt-and-mac, used by SSH, is vulnerable[br]to chosen cyphertext 0:12:07.660,0:12:12.230 attacks. There's a fun little paper on this.[br]Fortunately 0:12:12.230,0:12:18.089 the SSH protocol was extensible enough they[br]managed to 0:12:18.089,0:12:22.529 avoid, they managed to effectively fix this[br]retroactively. 0:12:22.529,0:12:26.300 So in review here, if we were trying to 0:12:26.300,0:12:30.470 build our own authenticated encryption scheme,[br]what we have 0:12:30.470,0:12:33.040 so far is sort of using AES in CBC 0:12:33.040,0:12:36.589 mode, since Ruby OpenSSL doesn't support countermode.[br]We're gonna 0:12:36.589,0:12:40.720 do the IP sect thing and encrypt-then-mac[br]and I 0:12:40.720,0:12:44.000 showed HMAC. HMAC is really nice cause it[br]takes 0:12:44.000,0:12:45.730 a lot of the sharp edges off some of 0:12:45.730,0:12:47.329 the other macs. 0:12:47.329,0:12:51.009 So what this actually ends up looking like[br]is 0:12:51.009,0:12:55.509 what's in Rails. The ActiveSupport message[br]encrypter. So this 0:12:55.509,0:12:58.139 is definitely a cool thing to use if you 0:12:58.139,0:13:01.379 just need to encrypt something and you're[br]using Rails. 0:13:01.379,0:13:04.370 It's definitely a way to go. 0:13:04.370,0:13:07.560 So let's talk about what else could go wrong. 0:13:07.560,0:13:09.560 Not done yet. 0:13:09.560,0:13:13.269 So the next thing is timing attacks on. So 0:13:13.269,0:13:17.329 speaking of that ActiveSupport message encryptor,[br]it used to 0:13:17.329,0:13:20.470 be vulnerable to these. So this is a patch 0:13:20.470,0:13:24.269 by Koda Hail to implement a constant time[br]comparison 0:13:24.269,0:13:26.519 of the mac. And the problem is if you 0:13:26.519,0:13:29.290 don't do this, the attacker can use this sort 0:13:29.290,0:13:33.870 of, like, infinitesimal timing information,[br]especially if they're on 0:13:33.870,0:13:35.370 the same LAN as you or on the same 0:13:35.370,0:13:37.720 host, to just try to guess at the mac 0:13:37.720,0:13:39.389 a byte at a time. 0:13:39.389,0:13:41.560 So you see before what it was doing was 0:13:41.560,0:13:45.120 not equals. So the problem with not equals[br]is 0:13:45.120,0:13:47.910 it'll sort of bail fast and exit early as 0:13:47.910,0:13:51.470 soon as it sees something that doesn't match.[br]So 0:13:51.470,0:13:53.980 by using the timing information off of that,[br]an 0:13:53.980,0:13:57.589 attacker can effectively guess the mac a byte[br]at 0:13:57.589,0:13:58.709 a time. 0:13:58.709,0:14:01.209 So the solution is all that nonsense you see 0:14:01.209,0:14:04.279 down there at the bottom, where they're doing[br]xor 0:14:04.279,0:14:07.240 between the two bytes and doing or equals[br]and 0:14:07.240,0:14:09.589 doing this over all the bytes and then looking 0:14:09.589,0:14:12.529 at the actual value of the result. 0:14:12.529,0:14:16.999 So this is all pretty crazy stuff, right.[br]And 0:14:16.999,0:14:21.699 we haven't even talked about pubkey. So really,[br]I 0:14:21.699,0:14:24.629 don't think amateurs should be trying to put[br]all 0:14:24.629,0:14:27.089 this stuff together. Unfortunately that's[br]sort of been the 0:14:27.089,0:14:32.129 state of the world in Ruby. 0:14:32.129,0:14:35.269 So what can we do better? We can have 0:14:35.269,0:14:41.610 more boring crypto constructs. So what, what[br]qualifies as 0:14:41.610,0:14:44.589 boring? Well, to do that, let's talk about[br]what 0:14:44.589,0:14:46.370 isn't boring. 0:14:46.370,0:14:50.410 So this has been how most things have worked 0:14:50.410,0:14:53.749 in the Ruby world. So OpenSSL is kind of 0:14:53.749,0:14:57.980 a terrible library to begin with, and then[br]pretty 0:14:57.980,0:15:00.589 much every Ruby gem you see that deals with 0:15:00.589,0:15:04.649 encryption just layers on a bunch of amateur[br]code, 0:15:04.649,0:15:06.430 trying to put all this stuff I just described 0:15:06.430,0:15:07.160 to you together. 0:15:07.160,0:15:10.910 And typically, they'll get at least one thing[br]wrong. 0:15:10.910,0:15:14.339 So, I'm not gonna name anymore names besides[br]that 0:15:14.339,0:15:16.910 Fast APS gem, because I think that one was 0:15:16.910,0:15:20.379 just pretty crazy and dangerous. But pretty[br]much every 0:15:20.379,0:15:22.600 gem out there, if you go through and you 0:15:22.600,0:15:24.389 try to look for all these things to make 0:15:24.389,0:15:26.790 sure they got it all right, they will generally 0:15:26.790,0:15:30.379 get something wrong. Oftentimes they will[br]not use a 0:15:30.379,0:15:32.809 mac at all, so they'll just use encryption,[br]and 0:15:32.809,0:15:37.139 the attacker can screw with your cypher text. 0:15:37.139,0:15:39.189 And then there's all sorts of other little[br]things 0:15:39.189,0:15:42.269 that they can get wrong which I didn't even 0:15:42.269,0:15:43.410 cover here. 0:15:43.410,0:15:49.009 So the boring approach in my opinion is to 0:15:49.009,0:15:52.029 use a crypto library written by cryptographers.[br]And when 0:15:52.029,0:15:55.129 I talk about a cryptographer, who am I talking 0:15:55.129,0:15:57.629 about? And it isn't someone like me, right.[br]I'm 0:15:57.629,0:16:01.389 a crypto enthusiast, but I'm not a cryptographer.[br]I 0:16:01.389,0:16:03.970 cannot design my own cyphers that will be[br]secure 0:16:03.970,0:16:07.689 yet. It's something I aspire to maybe, but[br]not 0:16:07.689,0:16:09.139 quite yet. 0:16:09.139,0:16:12.230 So what we really want is to bind to 0:16:12.230,0:16:16.120 a library that was actually written by cryptographers,[br]people 0:16:16.120,0:16:19.100 who spend all their time thinking about these[br]kinds 0:16:19.100,0:16:20.899 of attacks. 0:16:20.899,0:16:25.220 So I have written a library like this that 0:16:25.220,0:16:29.999 is actually a FFI binding to an actual library 0:16:29.999,0:16:34.529 written by cryptographers. So the name is,[br]unfortunately, a 0:16:34.529,0:16:39.379 little bit confusing. I call it RbNaCl, but[br]you 0:16:39.379,0:16:43.399 may also know there is Google native client.[br]It 0:16:43.399,0:16:48.430 isn't that. And there's also a, a, an ACL 0:16:48.430,0:16:54.139 organization that, in Japan, you might be[br]familiar with. 0:16:54.139,0:16:55.579 It isn't that. 0:16:55.579,0:16:57.600 So this is a library by this guy Dan 0:16:57.600,0:17:01.309 Burnstein. You may know him for libraries[br]like, or 0:17:01.309,0:17:07.930 projects like Qmail, DJBDNS, and DaemonTools.[br]And if you 0:17:07.930,0:17:10.470 haven't been paying attention to him for the[br]past 0:17:10.470,0:17:13.819 decade or so, what he's really going hardcore[br]for 0:17:13.819,0:17:14.720 is cryptography. 0:17:14.720,0:17:17.540 So he has designed quite a few of his 0:17:17.540,0:17:22.420 own cyphers. And all sorts of algorithms and[br]created 0:17:22.420,0:17:26.940 this NaCl library, which is slowly gaining[br]a little 0:17:26.940,0:17:30.880 bit of popularity. And you see the URL down 0:17:30.880,0:17:35.860 there. It's under the cryptosphere organization,[br]slash rbnacl. 0:17:35.860,0:17:39.780 So to make things even more confusing, this[br]isn't 0:17:39.780,0:17:43.770 actually binding to nacl, it's binding to[br]a portable 0:17:43.770,0:17:48.160 repackaging of nacl called libsodium. So the[br]best description 0:17:48.160,0:17:52.680 I've heard of this, is it's de-Burnsteinized.[br]A lot 0:17:52.680,0:17:56.070 of, a lot of people don't like DJB's bold 0:17:56.070,0:17:58.430 system, and it's kind of crazy cause the way 0:17:58.430,0:18:01.100 it works, once you bolt the library it's completely 0:18:01.100,0:18:04.710 non-relocatable, so you can't really package[br]it as a 0:18:04.710,0:18:07.140 binary for a distribution. 0:18:07.140,0:18:11.490 So libsodium took nacl and added a standard[br]automake 0:18:11.490,0:18:15.520 style build system. So it's easy to install,[br]it 0:18:15.520,0:18:18.310 is in Mac ports, and you can install it 0:18:18.310,0:18:22.850 with brew install libsodium. There are packages[br]for various 0:18:22.850,0:18:25.910 Linux distributions. Some of them, you know,[br]you'll have 0:18:25.910,0:18:29.330 to actually build yourself from source, but[br]the basic 0:18:29.330,0:18:31.690 work is there, and it's getting more and more 0:18:31.690,0:18:33.610 widespread option. 0:18:33.610,0:18:39.450 So nacl has many primitives. I'm only gonna[br]talk 0:18:39.450,0:18:43.490 about two here. So these are the symmetric[br]and 0:18:43.490,0:18:48.650 asymmetric encryption I was referring to earlier.[br]But it 0:18:48.650,0:18:50.910 also has a ton of other stuff, so it 0:18:50.910,0:18:56.790 has HMAC. It has digital signatures. It has[br]all 0:18:56.790,0:18:59.970 sorts of fun stuff for elliptic curve cryptography. 0:18:59.970,0:19:04.640 So I definitely recommend checking out. You[br]can go 0:19:04.640,0:19:07.140 to the rbnacl wiki and it has all the 0:19:07.140,0:19:12.220 features listed out for you. 0:19:12.220,0:19:14.650 So first I'm gonna talk about the symmetric[br]encryption 0:19:14.650,0:19:20.660 primitive it provides. So this is authenticated[br]symmetric encryption 0:19:20.660,0:19:22.160 and it is called secretbox. 0:19:22.160,0:19:29.160 So this may be a little hard to see. 0:19:29.320,0:19:33.150 But it should be fairly straightforward to[br]follow, I 0:19:33.150,0:19:34.590 hope. So what we're gonna do is we're gonna 0:19:34.590,0:19:37.460 make a key that is the size of a 0:19:37.460,0:19:41.340 secret box key. It's actually thirty-two bytes. 0:19:41.340,0:19:45.770 So you get a random key and that is 0:19:45.770,0:19:52.400 using rbnacl's own random number generation.[br]On Unix-like operating 0:19:52.400,0:19:57.260 systems it upholds from devurandom and on[br]Windows it 0:19:57.260,0:20:01.620 uses, I forget what it's called. Yeah. Windows. 0:20:01.620,0:20:05.190 Anyway. It does work on Windows. 0:20:05.190,0:20:07.200 So after we've done that, we're gonna make[br]a 0:20:07.200,0:20:10.840 new secret box with the key, and then here's 0:20:10.840,0:20:14.090 the fun part. We need to make a nance. 0:20:14.090,0:20:17.590 So this is just generating a random nance[br]of 0:20:17.590,0:20:21.080 the secret box's nance byte's length. 0:20:21.080,0:20:25.840 There's also another feature in rbnacl called[br]random-nance box 0:20:25.840,0:20:28.440 that'll do all this stuff for you. The important 0:20:28.440,0:20:33.260 part is a nance is a single-use value. So 0:20:33.260,0:20:36.180 every time you encrypt something with this[br]box, you 0:20:36.180,0:20:37.790 need to make a new nance. 0:20:37.790,0:20:40.650 So it doesn't actually have to be random.[br]It 0:20:40.650,0:20:43.540 could just be a counter. The nice thing about 0:20:43.540,0:20:48.010 it being random is it's long, so it's twenty-four 0:20:48.010,0:20:51.050 bytes, so if you just do a random number 0:20:51.050,0:20:54.080 every time it's hard to screw up. You don't 0:20:54.080,0:20:55.760 need to keep track of the state of how 0:20:55.760,0:20:58.580 many nances you've used. 0:20:58.580,0:21:01.150 So after that you hand the nance and the 0:21:01.150,0:21:03.820 message to the secret box. It'll make the[br]cypher 0:21:03.820,0:21:07.070 text for you. And to decrypt it, you give 0:21:07.070,0:21:09.630 the same nance and the cypher text and it 0:21:09.630,0:21:12.260 will decrypt. And behind the scenes, this[br]is doing 0:21:12.260,0:21:15.410 all the authenticate encryption stuff. So[br]it's adding a 0:21:15.410,0:21:18.470 mac, it's checking it, and it's using an encrypted 0:21:18.470,0:21:18.820 mac. 0:21:18.820,0:21:21.040 And then down there at the bottom, you see 0:21:21.040,0:21:24.540 if you try to open the box and something 0:21:24.540,0:21:26.940 is wrong, either the nance is wrong or the 0:21:26.940,0:21:29.890 cypher text has been corrupted, it'll raise[br]an exception 0:21:29.890,0:21:33.760 for you reliably. 0:21:33.760,0:21:37.260 So this is using a couple of algorithms designed 0:21:37.260,0:21:40.590 by Dan Burnstein. So the encryption cypher[br]is called 0:21:40.590,0:21:45.610 the XSalsa20, and the Mac is called Poly1305.[br]So 0:21:45.610,0:21:48.980 probably right now, you're thinking, what[br]the hell is 0:21:48.980,0:21:52.650 XSalsa20. Like, never heard of this. That[br]can't be 0:21:52.650,0:21:53.440 boring, right. 0:21:53.440,0:21:56.570 So I think this is boring because it is 0:21:56.570,0:21:59.550 a cypher that has sort of been standardized[br]through 0:21:59.550,0:22:03.040 this contest in Europe called ecrypt. And[br]the goal 0:22:03.040,0:22:06.130 of ecrypt is sort of like when there is 0:22:06.130,0:22:10.200 an AES contest. They're trying to produce[br]better stream 0:22:10.200,0:22:14.220 cyphers so the Salsa20 cypher was one four[br]they 0:22:14.220,0:22:17.610 selected for inclusion in what they call the[br]estream 0:22:17.610,0:22:18.740 portfolio. 0:22:18.740,0:22:23.350 I say this is boring because things have gotten 0:22:23.350,0:22:30.350 very not boring in the cryptography world[br]lately. So 0:22:30.690,0:22:34.050 you may have heard nist standardized a random[br]number 0:22:34.050,0:22:38.830 generator designed by the NSA called duel[br]EC DRBG, 0:22:38.830,0:22:43.090 and turns out that thing had a back door. 0:22:43.090,0:22:47.610 So there's still open questions about the[br]nist elliptic 0:22:47.610,0:22:50.900 curves as well and whether or not they contain 0:22:50.900,0:22:56.040 possible NSA backdoors. I mean, if you're[br]asking one 0:22:56.040,0:23:00.490 layman's opinion, I'd say it's probably unlikely[br]they have 0:23:00.490,0:23:04.860 backdoors in nist elliptic curves, but it's[br]hard to 0:23:04.860,0:23:07.120 know, and I think the boring thing is to 0:23:07.120,0:23:13.460 use cyphers that are beyond reproach. 0:23:13.460,0:23:17.740 So to take, to do asymmetric crypto using[br]the 0:23:17.740,0:23:20.500 same sort of primitives, we have this thing[br]called 0:23:20.500,0:23:26.700 box. And here is an example on how to 0:23:26.700,0:23:28.400 use box. So this time we have to actually 0:23:28.400,0:23:31.660 generate a random key. 0:23:31.660,0:23:35.020 So this is using that elliptic curve stuff[br]I 0:23:35.020,0:23:36.950 was talking about earlier. I'll get into how[br]that 0:23:36.950,0:23:40.520 works a bit later. So we take a private 0:23:40.520,0:23:45.190 key and, unlike RSA, with elliptic curves[br]we can 0:23:45.190,0:23:49.490 calculate the public key from the private[br]key. I 0:23:49.490,0:23:55.270 think I spot a typo there. Awesome. Oh no. 0:23:55.270,0:23:57.240 So yeah. So once we've done that, we have 0:23:57.240,0:24:01.760 a public key and you'll notice here when we 0:24:01.760,0:24:05.450 make a new box we're giving it both somebody 0:24:05.450,0:24:08.610 else's public key and our private key, and[br]the 0:24:08.610,0:24:11.220 neat thing about this is it's performing something[br]called 0:24:11.220,0:24:12.940 mutual authentication. 0:24:12.940,0:24:16.370 So all these boxes are based around a set 0:24:16.370,0:24:19.340 of keys. It's who you're sending the message[br]to, 0:24:19.340,0:24:22.340 and your private key, so that way when somebody 0:24:22.340,0:24:23.960 opens up the box, they'll know they got it 0:24:23.960,0:24:26.500 from the right person. 0:24:26.500,0:24:30.770 So make a new box. They'll also have a 0:24:30.770,0:24:35.070 box on the other side. It is effectively the 0:24:35.070,0:24:39.410 same box, just computed from the irreversible[br]keys. 0:24:39.410,0:24:42.070 So then after here it's pretty straightforward,[br]just like 0:24:42.070,0:24:45.760 the symmetric crypto. So what we're gonna[br]do is 0:24:45.760,0:24:49.230 make a nance again. We have the message and 0:24:49.230,0:24:53.200 we're going to encrypt the message under that[br]nance 0:24:53.200,0:24:57.140 and under that pair of keys. We get a 0:24:57.140,0:24:59.480 cypher text again and then the person on the 0:24:59.480,0:25:02.220 other side can open it, and once again, like 0:25:02.220,0:25:05.190 before, if it has been tampered with it will 0:25:05.190,0:25:05.740 raise an exception. 0:25:05.740,0:25:11.410 So box is built on the same primitives as 0:25:11.410,0:25:14.660 secret box, so it's still using the xSalsa20[br]cypher 0:25:14.660,0:25:18.640 and the Poly1305 mac. The main difference[br]here is 0:25:18.640,0:25:24.120 we're adding in a Diffie-Hellman function.[br]So that is 0:25:24.120,0:25:30.210 called curve25519. And that is an elliptic[br]curve algorithm 0:25:30.210,0:25:31.370 designed by Dan Burnstein. 0:25:31.370,0:25:35.260 So one of the big worries about elliptic curve 0:25:35.260,0:25:38.850 cryptography, in addition to possible NSA[br]tampering has been 0:25:38.850,0:25:43.860 patents. So DJB has designed this curve specifically[br]to 0:25:43.860,0:25:46.680 side-step all the patents. It's pretty awesome.[br]If you 0:25:46.680,0:25:49.570 go to the website for it you'll also add 0:25:49.570,0:25:52.070 the patent, and he lists out the prior art 0:25:52.070,0:25:55.490 saying this patent is bullshit, anyway. But[br]then he's 0:25:55.490,0:25:59.330 like, here I completely avoided that problem[br]entirely. 0:25:59.330,0:26:06.330 So really quick, here's how Diffie-Hellman[br]works. SO it's 0:26:06.600,0:26:09.910 pretty simple. What we do is a thing called 0:26:09.910,0:26:14.950 scalar multiplication. So we take Alice's[br]private key and 0:26:14.950,0:26:18.530 perform a scalar multiplication operation[br]with Bob's public key 0:26:18.530,0:26:20.900 and we get a shared secret. 0:26:20.900,0:26:25.660 And Bob is able to calculate the same secret 0:26:25.660,0:26:29.500 by multiplying his private key by Alice's[br]public key. 0:26:29.500,0:26:33.770 So these two, two operations are sort of like 0:26:33.770,0:26:35.640 a reflection of each other. 0:26:35.640,0:26:40.940 So secret, box works by taking that shared[br]secret 0:26:40.940,0:26:42.940 and using it to drive a symmetric key. 0:26:45.860,0:26:50.000 And that's all I got. Keep it boring.