 All right, cool, happy Monday, room full of people. Let's start where we left off. Anybody start on the homework yet? Yay, we all did because we do what is told of us to set us up for success in the course because starting the homework assignments early will always guarantee them that you don't wait till the last minute to do them. Cool, so last class we went over classical cryptography, we went over symmetric encryption. We showed, we talked about one time pads and then we showed how to process stuff using Pone College with using specifically Pone tools to access and execute a process, read input and be able to extract the things that the challenge wants. Cool, so now we're gonna continue so that you can solve multiple challenges and we will be expanding our knowledge of encryption. Okay, so we last talked about DES. So DES, what type of encryption algorithm was DES? Like how would you use DES? DES, what was DES five whole days ago? What was it? A symmetric key algorithm. What does a symmetric key algorithm mean? Somebody else, I can start calling on random people. That seems less fun. Yeah, all the way in the back. Yeah, it uses one key for encryption and decryption. Yes, it uses one key for encryption and decryption meaning that the sender and receiver of the messages Alice and Bob need to somehow securely share that key because anyone who knows that key can decrypt the message. And so the security there is all predicated around not releasing that key and the security of the key. Okay, great. So DES, which was again established in the 70s. What's kind of crazy is it actually stuck around for a long time. We talked about, so AES was standardized in 2001. Key aspects of AES that are important for us is that it has an 128 bit block size. This is something that's gonna be super important to keep in mind as we tackle challenges involving AES. So 128 bits is also 16 bytes. You could calculate that yourself. How? What was it? Divide. Divide, what by what? Eight. By eight, yes, 128 divided by eight is 16. So that's how you can come to that. I didn't just memorize this. I looked this up before class. So that way I could appear smart in front of you. But all you have to do is just divide. So how many bytes is that? 128, it's 16. It also allowed the key size to be either 128 bits, 192 bits or 256 bits. And I think we talked about this very briefly, but it's actually, like depending on the size, it can be used to secure classified information up to the secret level. Top secret information will require the use of either the 192 or 256 key lengths. This is interesting. The implementation of AES and products intended to protect national security systems and or information must be reviewed and certified by NSA prior to their acquisition and use. Why do you think that is? So that they get backdoor it? If they're gonna use it on their own systems? I mean, that is one theory. What would be the other theory? Yeah, so they'd wanna ensure that it's secure before it's used in national security. This doesn't say that implementation of AES and products intended to be used by you on your cell phone will be reviewed by the NSA. This is only if it's gonna be used for government purposes. So yeah, I think we can, it's kind of an interesting debate of would they introduce a backdoor? I think the main thing that we've learned is that once you insert a backdoor, it's very, very difficult to guarantee that you're the only person with that backdoor. So if that system is being used to encrypt your secrets and it has a backdoor, if your adversary discovers that backdoor, then boom, they have access to all your secrets. So it's usually not a good idea. Cool, okay, yeah. Intel extended x86 to include AES instructions directly in the hardware. So we can look at a high level what AES looks like. It's not too different from the DES, the, you know, this is again, all just permutations and substitution ciphers, just a lot of them and very fast. I keep clicking next. Cool, so yeah, there's a bunch of operations that happen here and all these tables and there's multiple rounds of this and keys get used and XOR and all this stuff. But for our purposes, since we looked at kind of how DES operated, we're not gonna go into the details here. Let's just, we'll stick in the high level of thinking of AES is a box. So it's a box where plain text goes into that box, a key goes into that box and an output cipher text. So what are the sizes of keys? So this box, how big can this box be? 128 bit, 182 bit or 256 bit, right? What about this plain text box? Yeah, we didn't quite talk about it, but implicit in this block size, 128 bit block size, this means that the plain text data that can be encrypted or decrypted by AES is only 16 bytes. And so it mixes that with the key to produce cipher text so that it should be impossible for somebody to go backwards from the cipher text to plain text unless they have the key. What's the other way that they could break it? Group forcing, so you get some cipher text, you try all two to the 128 keys. How long is that gonna take you? How many, what's two to the 128? Yes. What? Yes. The answer's just yes. It is 3.4 followed by, what is it, 10 to the 38? So it's like 38 zeros or something like that. I like using Wolfram Alpha for these questions because it does it really nicely. Two to the 128. So this means you will have to try. Oh yeah, that's a great number. So this is, I can't even figure out what that is, but... It says it right. Oh, great, great, great, thank you. This is 340 billion, billion, billion. Oh, why is there still dots? I want the actual form. Oh, there we go. 340 undecillion. Nice, pronounce that right, who knows? 282 decilillion, 366 nonilion, 920 octillion, and so on and so forth. All of these are more than a billion. So these are all several orders of magnitude more than a billion with 39 decimal places. So you need to try each of those. If this was, let's say each tribe took you half a second, that would be, expand that out. That's the whole point of this exercise there. 3.9 times 10 to the 20th of the age of the universe in years, 3.5 times 10 to the 30 years. Let's say you do it like real fast, right? You're still talking about like multiple, multiple lifetimes even if you made this faster, right? For this to be fast, you'd have to do it, I don't know, like, yeah, you'd have to solve it like almost instantaneously. Oh, now we're down at 10.79 trillion years. Then there's another problem. You try all these keys, you have this 16-byte cipher text that's gonna output 16-byte plain text. How do you know which one? So it's gonna generate two to the 128 possible plain texts. How do you know which one is the actual plain text that the original message was? Maybe you know something about the original message so you can tell of all this gibberish what it is, but anyways, the point is it's gonna take you a long time and it's what we call computationally infeasible to do this with modern systems and even modern hardware. See how fast, like, how insanely fast? And that's okay. So we've got it down to 1 billion years. So let's say you had a billion years to spend on this problem. This means you'd have to do each try in, I don't know what any of these things mean if anybody has a good, yeah, about the half-life of hydrogen four seconds in nano. That's one times 10 to the negative 13 nanoseconds. So you have to solve these, like, to what? Blank time. Blank time? Blank P-length. Oh, P, I don't know what that is. What is that, P-length? Oh, plank. Cool. All right, there you go. So 1.85 times 10 to the 21st plank times. That's a natural unit. This is fascinating. Okay, we've got to stop. Okay, there's no limit in physics to do this, so. But you're still gonna wait a billion years even if you can accomplish this, right? So getting that down to days is gonna take a lot of time. So for all intents and purposes, when we see the AAS block, we're gonna say that that is a good, so one of the things is maybe you could guess the key if it was not. So our brute force strategy for the key required it to be uniformly random, right? Every single of those 128 bits were equally likely to be one or zero. But if, let's say you knew the key was a past phrase or some English word, then your knowledge of the key space would be significantly reduced. Okay, so anyways, super important thinking about it. So we can only encrypt things in 128 bits of information. Why is that, so 16 bytes? Why is that useful? That seems not useful. Like, have you ever wanted to converse with somebody with more than 16 characters? Yes, like this entire content of this lecture and everything, there's more than 16 characters. Right, there's already more than 16 characters in the Twitch chat, think about like, so like done, chat over, send message. So we have to talk about how we actually deal with that. But right now just looking at this encryption function, looking at AAS at the base level. So we have, so now we need to encrypt the string hello comma space world. So we can again, we're not gonna operate, we're gonna translate those, obviously they're ASCII representations. So we have the ASCII values here, but this is one, two, three, four, five, six, seven, eight, nine, 10, 11, 12, 13. It's 13 bytes. What do we do with those other remaining three bytes? Yeah, we need, because the question is, but the question is what padding to add and how do we separate that from a message that has that padding, right? Because I would wanna be able to send a message that's any possible 16 byte value. So fundamentally, this is the key problem with these, what this is like fundamental problem with these encryption algorithms is with these block ciphers, we have to send data in at least a 16 byte chunk. And we'll show how we can send multiple 16 byte chunks. So one thing that we can do is have null bytes, right? So this was the suggestion, or it wasn't exactly your suggestion, but some kind of padding right at the end. And so we'd say, okay, so our encryption scheme now is, let's send a message, encrypt it, and then when we get null bytes at the end, we'll just knock that off when we decrypt it. So we'll say this was the original message. So the problem here is now we can't tell the difference between two messages or three messages or I guess four messages, right? There's several possible versions of plain text that this could be. It could be the string hello world that they wanted to send. It could be the string hello world null byte, hello world two null bytes or hello world three null bytes, but we can't tell which one that is with this padding. So there was a different scheme that was created. And I guess we could look up exactly what this means but pkc seven. So the idea there is, and the other problem, yeah, the problem with these null bytes is it's really difficult to tell. Yeah, like we said, which ones were null. So anyways, the idea here is for padding, you pad with bytes that are the number of bytes that you want to pad with. So for instance, here, there were three bytes extra at the end. So there's gonna be three bytes each with the hex value three, oh three, oh three, oh three. That way when you decrypt, you look at the last byte, you say is it three, three, three, and then you cut three bytes from there. You make sure those are all three. If it's two, you'd only cut the last two bytes. If it's one, you cut the last byte. What if it's zero? Yeah, you can't have that situation. So you have to have a new block, like a whole new block of just 16 bytes. So you can never, you should never have something that is a full block. Is that correct? That is correct, right? Yeah. So padding will either be 16. So the whole block is padding where it'll be 15 with one byte of plain text or 14 with two bytes of plain text or 13 with three bytes of plain text. Everybody getting the pattern here? I can keep going until we get there. Yeah. So if you have like 15 bytes and you're padding with one, how can you tell like, it's not hard for us to go where it should be? Say it again. So say you like got 15 bytes. Yes. And you're padding one bytes. Yes, you would have one. So the very last byte would be one. So on decrypting, you check that one and you would only remove that one byte. How do we know it's not called it's the origin? You know that anyone encrypting with this scheme? Well, you know, because if it was a zero, you would have a second block that had 16. 16, 16, 16, 16. Yeah. So then decrypting those two things. Actually, your point is very good because it gets into an interesting situation that actually gives rise to an attack where you as an attacker can lock off the last block and have it decrypt things to try to infer things about the plain text. But that's a more advanced thing than we'll cover here. But yeah, like that's why when you start adding these schemes to deal with these problems, you'll see like problems do emerge, which is kind of crazy. Okay. So when we encrypt, we encrypt this. So we encrypt it. Now we've padded it. Now we've got exactly the block size. And now when we decrypt the cipher text that we just got, now that decrypts and we have 16 bytes and we lock off the last three. And then boom, that is our plain text. Now we have that problem of, okay, what if we want to send more than 16 bytes? So here we have a bunch of hex characters. So what we do is we will first take the first 16 bytes, encrypt that and not pad that because there's no padding there. Then we take the last 16 bytes. And of course, if there's any more, like that will be less than 16 bytes, like here, here, I don't know if you can, oh, you can see it up here. It's 06. So there's six bytes of padding here. And then we encrypt that and then we send those two blocks. And this gives us rise to the scheme, sorry, on the current slides that are posted, it is the font was white and I could not figure out in time how to change it and to make that diagram have black lines. So now it's gonna be, these slides will be black background with white text. This looks better than my diagram. It's fine. Maybe better in here, whatever, doesn't matter. So this gives rise to a scheme of how do you do this? And so there is a, the technique is called the ECB, Electronic Code Book, which basically you take all of your blocks, you split it up, do the padding, like we talked about, once you do the padding, now you have exactly a multiple of the block size of 16 bytes. And then each plain text, so the first 16 bytes gets passed to the encryption with the key and then the cipher text and then the second block with the key to the cipher text, seems good, right? And then to decrypt it, you just do the reverse. Make sense? Yeah. So, unfortunately, and this seems like, so again, did we talk about it? Are we assuming any breakage in this encryption algorithm? So what I mean when I say that, what I mean is if there's a single bit changed in the encryption algorithm, if it changed in the plain text, the cipher text will be wildly different such that you will never be able to tell. So there's no way of inferring what exactly that plain text is based on a one-bit flip. And this key is random, so we'll assume that the key is randomly generated, you can't guess the key, there's no breakage there. So for this scheme to work, for any of these encryption, what if this block of plain text is the same as this block of plain text? What will happen to the cipher text? They'll be what? They'll be the same? Can they be different? No, why not? Yeah, it's the same key and it's gotta be able to go backwards. So if you had two different input, the exact same input to the encryption function with the exact same key that produced two different outputs, you have a really messed up and broken symmetric encryption algorithm because there's no way to go backwards. Which of those two messages or which of those was it? And that actually, so this seems kind of crazy. So this scheme, which is, let's say the math is, I don't know, the math is perfect, the math is good, but just the fact that I can tell as an attacker that these two blocks are the same if the plain text is the same, can leak information about the plain text. And so this is one of the best examples of this, this is the Linux penguin and this is the Linux penguin encrypted with ECB on the right. So if I just gave you the image on the right, would you be able to tell me anything about the message? It looks like a penguin which is violating exactly what we want. So we use these beautiful cryptography algorithms, right? This math that we created, we had this contest about AES, it's implemented in hardware, it's super fast. And we do that and run it through this ECB and then we can still leak information about this image through this scheme. Kind of wild, right? So you're gonna fix it, how do you fix it? So maybe change the key so it's like a different key every time? Yeah, that could be definitely one way. The other way to do it, the really nice thing is if you look at here, so this is the first block. So you take the key, get some plain text, you get some cipher text. This cipher text is essentially random, right? It should have no relation. It's based on a random key, random plain text. It should be random values. So the idea is if you take that, XOR it with the plain text here before it's encrypted. Now, even if this plain text and this plain tests are exactly the same, the resulting cipher text will be different. And that's exactly what cipher block chaining is. Another mode to use AES. So ECB, you should just basically never use. We use it as an example to show why it's so bad. So cipher block chaining is the technique where you take the plain text, usually also have an initialization vector. This is something that's public. It's a random value here. But you take the plain text, XOR it with this initialization vector, and then, yeah, send it to the encryption, then take the cipher text that you got out from the first block, XOR it with the plain text of the second block, encrypt that, and so on and so forth. This actually, you may be wondering about our fine friend, I think it has a name, is it Tux? Yeah, our fine friend Tux, the penguin, who's not really wearing a tuxedo, so it's kind of weird, but anyways. So this, now that exact same thing encrypted using CBC, now we have the image on the right, which is actually visually looks gibberish, which is exactly what we want. What's the downside of this approach? Your first block is on, the rest will be on. If your first block, yeah, so if you, maybe another way to phrase that, I guess would be if there's any problems in the transmission of the cipher text, let's say. So if the cipher text gets a bit flipped, the whole thing is garbage, whether with ECB, if a single bit messed up in the cipher text, I could still decrypt all the other blocks. What else? Yeah. Probably at the same point, I'd like to cancel my speed integrity problem, whether it's important to correct or not. Yeah, so the, it's a problem with all these, we haven't talked about integrity at all, because that's something we have to do separately, but yeah, that's a big problem too, is dealing with this problem of integrity and if any bit flips change, then we have problems. What else? How would you implement this? Sorry, my watch is buzzing. Somebody just shot something wrong. Okay, so if there was, yeah, so think about how you implement this, right? So with this, so you're implementing this encryption, say, okay, get the plain text, get the initialization of XOR, XOR it, pass it through the encryption thing, then get the cipher text and then do that again over and over in an iterative loop. Can you start encrypting the third block? No, you have to wait until you've encrypted blocks one, two and three versus with ECB, it's actually very nice parallelism where you could encrypt each of these separately. So think you have a, but modern CPUs can have eight, 20, 40 cores depending on the server or whatever. Each of those could be doing encryption stuff in hardware with ECB mode. So you're giving up this parallelism here, but the clear security benefit is much better. So it's useful to think about. Okay, but there's one more type of encryption mode. This is the counter mode, CTR. So this one's kind of interesting because it allows you to, it kind of solves the challenges of both, allows you to actually do the encryption in parallel while still maintaining this notion that you want, that a single plain text input plain text block should not result in the same cipher text block. So the idea to this scheme is you pick a random nonce and then you, the funny thing is rather than actually passing the plain text through the cipher, you're essentially using the count, the encryption algorithm as a random number generator that deterministically based on your nonce. So you take a nonce, like you start at some value and then you add one to that nonce each time. So this is counter zero, counter one, counter two. You encrypt that with the key and then take the plain text and XOR that with whatever came out of there to get the cipher text. So you can only, we know with XOR, so you should only be able to get back this plain text if you have the output of this box which should be random and based on the key. So it's protected by the key. And then to decrypt you just do that in reverse. So you communicate the nonce so that you can calculate this and now the nice thing is you can do this on each of the things in parallel. And so here you get the, you do that encryption, you get the cipher text XOR it with whatever comes out of this box. And remember whatever's coming out of this box on both sides is the same. And then you XOR that to get back the plain text. Kind of crazy. But there are other ways to mess this up. So if you reuse the same nonce and counter again, that can cause problems. I think you can have, remember correctly you can have problems with the counter wraps around too and re does stuff. So anyways, there's interesting ways that this can break or if you can get it to use the same nonce, you can force a nonce, you can get the same output here to break things. It's all kinds of cool stuff. Okay. Questions on this? These modes. It's kind of crazy. So this is all the stuff that has to go on top of these encryption algorithms. And if you mess, like this is what I love about this and this is what we're going to get to is, so even if you do this, even if you, the encryption algorithm is correct. So like we saw how to break Caesar Cipher and other kinds of classic like old school crypto stuff. But this is even on new stuff, assuming that this is unbreakable to use these in a real world setting, you have to use these different modes and each of them has different trade-offs that can cause problems. Okay. So we are going to look at how to attack ECB. So we looked at that, the repeating patterns, but a question that should arise to you is like, okay, sure, that leaks some information. Yes, I know that it's a message of tucks the penguin, but how can I actually like recover information from there? And so like I mentioned, when we were talking about padding, there's a whole thing called a padding oracle attack that you can use to try to leak information. We're not going to go into that now. The other thing is what control do we have? So we'll see right now a prefix attack where secret data is appended to our data. So our data goes first and secret data goes afterwards. And we'll look at how to use that to break ECB. So let's stop here. Level five. Okay. So this is where you can already see what the solves. This is where things get harder, right? That's because we haven't talked about it yet in class. So let's look at the challenge. Okay. I'm gonna do it in my terminal because I want to. My video just cut out, no? Why is it blinking at me? This thing is favorite. Yeah, well, I'm talking. The AI should know. Okay, challenge run. Welcome to cryptography. In this challenge, you'll decrypt a secret encrypted with AES. The ECB block cipher mode of operation is used. You can encrypt arbitrary data, which has a secret appended to it with the key being reused each time. So if you've already looked at this level, it may look slightly different. Before class, I added this hex output, which should help us in our discussions of what's going on here. But just like all the other challenges that we looked at, so it's telling us the secret cipher text B64. So here it is. And then this is the same thing in hex. And so we can already see, so we could count this. This is 32, or sorry, 16 bytes. So each of these corresponds to a block of output from AES. Let's see, I'm just gonna feed this back in to see what happens. It's actually kind of cool. So we should see, will we see them repeating? No, it depends on how it's actually done. Anyways, so we see that by adding more things, let's actually look at what's going on here. And you can do this. This is like totally allowed, right? The challenge run is just a Python script. So you can look at it. So, and it's very simple. So that's the other cool thing that I like about this is showing that these challenges are not crazy difficult and these crypto schemes that we are using are also not very difficult. But even like this, they can be done in a way that messes things up. So, key, get random bytes 16. So let's just assume that that's correct, 16 random bytes for the key. Create a new AES cipher using mode ECB and using the key we just created. So first thing it does is get cipher text. So it calls this pad function. So the pad function does the PKC7 padding that we just talked about. So it gives it the flag and the block size and then uses the cipher to encrypt that. So we can think of the cipher text, which is the flag, got padded out and then got sent and encrypted. And then that's exactly what the cipher text is. So show base 64. So it shows us the cipher text base 64 encoded and it also shows it as a hex block of the cipher text. And then in a loop. So while true means forever, do this. So get a base 64 input. So that's our plain text prefix. Then pad the plain text prefix plus the flag with the cipher block size, pad all of that, encrypt it, and now show it to us and just keep doing that over and over again. So the crazy thing is that we can leak the flag and read the flag, get the contents of that cipher text just with this power. Like this is enough power to get us to get the flag. But first let's kind of poke and see what's going on. So I am going to have two screens here. One will be ipython import base 64. And the other thing is that we should note, so the cipher text is changing every time, right? So it's different here. It's different here. Why is it different here the second time? So the key is changing, but not the plain text data, right? The plain text data, we could look, but it's the flag it read the flag earlier in the file. So it's reading the flag. So this is what, again, the similar thing. This is why even though we know parts of what the flag is, right? Do we know what the flag starts with? Yeah, and do we know what it ends with? Curly brace, yeah. So we know stuff about what the flag should look like. But even with that, every time we run this challenge, it'll be a completely different cipher text. We'll get different cipher text. So this also tells us that we can't just do this offline. Like we can't do this by hand. We'll need to write programs that do this. Let's look at this. Okay, so this is one, two, three, four blocks, right? We could, do we know how long the flag is? Why yes. Yeah, I don't know, you tell me. Are you sure? Yeah, so here's flag, flag open slash flag. Why no? I just don't know. Yeah, so it's hard to tell, right? Maybe, you know, you could make a guess about the flag based on the previous flag. Maybe you go back, solve an easy challenge to get a flag, see the length. You don't actually need to know exactly how long the flag length is. We'll show, because so let's look at what we're doing right now. So I do run, I have the base 64 here. So I'm gonna do base64.incode. I'm gonna do the empty string. I'm gonna print this out. Okay, sorry, it's B64.incode. Ah, the empty string. Is that true? Okay, perfect. Yeah, so if I don't input anything, it's the exact same output. Everyone agree that this all is the same output? Yeah, cool. That's a good base case. Let's say I wanna add one A. So one A will be, I'll just copy it correctly. Like this, okay. How many blocks do I have now? Same number, four blocks. Right, when I put in nothing, I have four blocks. When I added one character, are these blocks different? Yeah, they're all different. So what does that tell us about the length? Or why, why is it still the same number of blocks? I gave it more data. It's not probably, it must be the padding, right? If I added a character and it went into a whole new block, then we knew, well, we'll talk about what we know then. But yeah, so we added one A to the flag. And it's the same number of blocks. Let's add two A's. Yee-wee. Okay, same number of blocks. Four, three blocks. Base 64 is so weird. One, two, three, four, four blocks. Four characters, still four blocks. Okay, okay, still four blocks. I could also, I guess, binary search for this, but that's okay. Let's just keep doing that. Four blocks, four blocks. This is exciting, huh? I shouldn't think this class was just counting. Four blocks, it's gotta happen soon. Four blocks. How many are we up to here? I feel like I can't stop now. Oh, there we go. Woo, look at that. All right. All right, woo, that was a lot. One, two, three, four, five. Okay, so I had to add one, two, three, four, five, six, seven, eight, nine, 10 A's to the front of it to have there be an additional block. Now, how can I use this information to know how many characters there were originally? Louder? Yeah, so the, okay, so let's think about it in different ways. I think you said key, but you meant flag, right? So the flag, so the art input added to the flag. So we know, let me, I'm gonna start drawing now. I'm gonna try, does that work? Can you see that? I don't wanna say hello. So that was five blocks. So we had A, looking like this. So 10, right, 10 total characters here, plus the flag. That output, two, three, four, five blocks. And we also know, sorry, I need to, we also know that nine, nine of those only resulted in four blocks. Okay, so this means that or should mean if we did everything correctly. So when is a new block added? Once we exceed what? Yeah, so once between nine and 10, so at nine, so we know actually that this bottom here, this block will have nine A's and then some of the flag, this one will have flag, this one will have flag, this one will have flag. How much padding is there on this one? Normally we wouldn't know, but if you add one and a whole another block appears, how much padding is here? Four answers now. Somebody reasoned it out, yeah. Oh, zero. Zero, if there was zero padding here, we'd have another block, because a new block has to get introduced if ever we have, 15 bytes of padding. So specifically on this one, so on nine, right? So we input nine A's plus the flag and then we input one more and then we get five blocks. Yeah, that means there has to be one padding byte here, right, which also means that this whole block is all padding. So this is gonna be a block that's only, there's 16 bytes and the padding scheme with 16 bytes of padding, what's each byte gonna be? What was it? Not null, that's a different scheme. PK, yeah, zero 16, the whole block, zero X 16 in here, this block, right? Is that not correct? Oh, that's true. Good, good, good, thank you. As you were looking at me funny, hi. Couldn't figure out what it was for. What is 16 and hex? Oh, one zero, that's right, that makes more sense. Good, see that was a test. So you didn't even know that at the start of the class. Look at you, you're correcting me once Connor points out something's wrong, cool. Okay, which means that this is 10 bytes of the flag of A's, right, 10 A's and then how many bytes left in that block? Six, so six bytes of the flag, how many in the second block? 16, 16, 16, so this means our flag will be whatever this is. Oh, but I have Python for that, I don't need you. 54 bytes and oops, I'm covering the screen, 54. And we know exactly what the content of this block is, right, we know the content of that block is all zeros, or sorry, 16, yes, thank you, hex 10, 16 of those encrypted. And we control, so we control input, what if we give 16 bytes, everything gets shifted over but that first block, whatever that output is, is whatever we say it should be. So now we can test our theory. We can say, okay, this is, we just reasoned with ourselves and as a group and said, okay, there are four blocks here, I know this block is first 10 A's and then some stuff after it and I know this one is flag, flag, flag and I know this one is hex 10 or 16, 16 bytes of that. Now, let's verify that assumption. So in case you don't know, Python has this really nice slash nice slash super weird syntax where if you multiply a single character or string, actually I think it's anything, by a number it will duplicate it that number of times. This is how you can do really nice things like and not have the type slash 10, slash 10, slash 10, slash 10, slash 10 every time. So we can say, okay, what is, what if I gave this as input? So this should be a block full of 16s. I really hope this works. Oh, look at that. Boom, this is the exact same hex value. Ever seen this? This is insane. So we've broken through this encryption in the sense that we now know exactly what this block is. I mean, for that, based on in changing the size until a new block appeared, we knew that the content exactly of those new blocks. It's pretty nuts. Be more excited. Wow, that's so cool. Look at this, we're learning attacks. Okay, so what happens? So this is, we know exactly where we are with 10. What happens if I do 11? What happens if I give 11 As? They'll still be flag box, excellent. So I say, A, actually, let's, oh. So this is how I do all this stuff is I just like write out what I think, what's happening. There's a lot of stuff I don't know about the input, but there's a lot of stuff I do know, right? I know there's 11 As. I know there's a flag and I know that's exactly 54 bytes now, right? And so that will result in how many blocks? Five blocks. So what do I know about the first block? 11 As, boom. So it'll have 11 As, and then five bytes of something I don't know. Will I be able to tell anything about these two blocks? No, they should be completely different, right? Completely different. I should be able to infer no information from that. Okay, what about the next block? 16 bytes of the flag and the next box, and then this box, what about the last box? One byte of the flag. What about the rest of the content? Yeah, hex what? Or hex 15, or hex 16, or decimal 15, because there's 15 bytes of padding. So this will be one byte of the flag and the rest will be 0x15. We actually already talked about it. Do we know what that byte is? What was it? Curly brace. Yeah, it'll be the ending curly brace. It should be, but what if we didn't know that? So we have a case here where we have one block. We know 15 bytes out of 16 bytes. How can we figure out what value that is? Yeah. So if I then were to do exactly what we did here of encrypting, using a block of 16 in order to use it to encrypt something. Now I could try, so I could try something like a, what would this be? 0f times 15, right? So this will then tell me, so this is a block that has a first character a and then 15 bytes of 15. So if I do this, compare the first block with the last block, is it the same? No, we know it's not correct because we know that's not the value. We can do this for A, B, C, D, E, F, G, everything, all the ASCII characters. We can even do all 200. It's only, how many guesses do we need to guess? 256, which is pretty easy. That's not a lot. Is that less than 300, 340 into bajillion? Yes, way less. Like you could write a program to do this easily. Now let's try, our program will go through, it'll try all the values. At one point it will try this and that won't work either. Why doesn't that work? Now the question is, did I mess something up? Where was it where we, now we gotta start from the beginning. This was 11, did we ever do 11? Oh, we never actually did that, did we? Dang, that's funny. Okay, all right, let's simplify this. We never did 11, let's do that. Okay, this is the, now we should be, according to our diagram, 11 should get us our last one, then should be the last character of the flag and 15. That should be this, so this is our target. Okay, and let's check if this works. I'm gonna double check that this works. I'm gonna calculate the length of this, 16. I'm gonna look at it to make sure it looks right. Okay, that seems right. 15, one, two, three, four, five, six, seven, eight, nine, 10, 11, 12, 13, 14, 15. Okay, so let's take this. Okay, that did not work. I think I know the problem. We would, I don't wanna ruin this. I'm not trying to get there. Why did that one? Wait, louder? Sir, in the third line of the top, the last block started from eight, six, three. How did it, so it was at the top, and now it's at the bottom, how did that happen? Okay, now you know, the computer told you. So this block, let me see, is, why did that repeat? Yeah, that's all right. Oh, that is because this here, this EB, this is where we had the block of 16 characters of byte 16. So this example showed when we put in 10 As, the very last block, we knew exactly what it is. Okay, I do know the answer. The actual last, so the last character of the flag is always an ending curly brace, but there's usually another character after that. You're just reading the flag. Not a null, yes, a new line. There's actually a new line at the end, which was a great test. Let's see if that is correct. And so if I wanted to figure that out, I would go into practice mode, I'd use sudo to count out a flag and look exactly what it looks like. And this is also a good reason why when you're, whatever you do a brute forcing thing like this, it's probably a good idea not to restrict yourself to just ASCII character, like printable characters or whatever, just like try zero to 255, like try all the characters to see which one it is. I say that confidently, hopefully that this works. Hey, there we go. So we now have guessed properly exactly what that byte was when we passed in 11. So this was our try 11, the very last block had one byte of the flag and padding. And then when we guessed in this last one a new line, so what happens when we go back here and we inductive reasoning about what happens when we apply 12? Yeah, then how many bytes, first, how many bytes of the flag are in the last block then? Two bytes in there. And we already, which of those bytes don't we know? Yeah, the first one. So we still know, and we know what's the padding if there's two bytes of the flag in there. Yeah, E, hex E or 14, right? And so we can do exactly the same process again. And now we can theorize that that is a curly brace. And so we'd first give it, what is 11? Where's my AS, yeah. So now we're gonna give it 12 AS and this is the last block, D670. And we're gonna say, okay, what about end curly brace slash N and then E, 14. Boom, there we go. Found that exact same block. So by doing this and continuing to apply this, we can leak out the flag by byte by byte and be able to completely recover the plain text data even though we're using everything correctly, right? It's a random key we don't know. It's using AES correctly. It's just because we can influence this with the padding and we know the padding scheme that we can do something like this. It's pretty crazy, right? You all agree? Thank you. I appreciate your enthusiasm. Questions on this? Yes. So I just wanted to add a little bit of like, so she had like 16 bits of 8x. Louder? So she had like 16 bits of 8x. Mm-hmm. Then the next block would have an x16. Exactly. Yeah, so if you have 16 bytes, because if you didn't do that, there's no way to tell it there's zero padding because you need that last byte to tell it that. So the way you do that is by having a whole block full of 16s, a whole padding block. So if you give me 16 bytes, I will give you two blocks back. Yeah. Cool. More questions on this? Sorry, I'll go to Twitch, Evan. I was drawing. And so now the fun part of level seven is coding this. Or you could do it by hand, I guess, if you really hate yourself. 256 guesses is a lot, especially for we know it's 54 characters. So we did two characters. And the two characters that we knew. So, but once you get this method, right, you can, once this is automated, you're doing this byte by byte. So it's not that, it's not that crazy. You do have to be careful about which blocks you're doing and making sure you're getting it correctly. But it's, yeah, it's very much this process, this exact process, right? Just like over here, we knew here that this was a curly brace, but we could try everything from the zero byte to the 255 byte. And one of those will match exactly. And we'll know exactly what that byte is. And then we could go on to the next character and leak more. So you're leaking the flag from the back, basically. For, we haven't talked about seven yet because that's what we're covering next. Cool, all right. Speaking of, let's learn some asymmetric cryptography. Question on the chat. How do we use Pondles to pass input to the program? Check out the lecture from Wednesday because we covered that in class and wrote a little program that did that. So building on these two things, I'm highly confident you can do this. This is one of the like very cool kind of crypto style attacks that are real attacks that actually happen that people do. Okay, all right. So we talked about symmetric crypto systems and we've kind of been covering under the rug this problem that, hey, there's this key, right? We saw with AES, 16 bytes of random key data, but how do I transmit that to somebody, right? It's almost like a recursive problem. It's like, okay, but, or it's like a, I don't know. It's a problem that like, okay, but you transfer it securely, but like, yeah, that's why I'm doing these keys so I could talk securely. Like, if I had a great way to talk securely to somebody, I wouldn't need all this other mechanisms and all this stuff. So this is like the key problem. And so there was a major breakthrough in cryptography, which the idea, and this is where asymmetric comes in where the goal is, how can I encrypt information without requiring some shared secret key that we have securely transmitted to each other. And it's honestly, I like vaguely, I think I mentioned this on Wednesday, I vaguely understand the whys of how this works, but to me, this stuff is like magic and it's super cool that this works. And this is like why math is so interesting. The idea is now with asymmetric crypto systems, everybody has two keys, a public key that we'll call P that they share with everyone. So everyone knows your public key. And so Alice and Bob, we can say have public keys A and B and we, everyone also has a secret key that they keep that they never share with anyone else. So we use S for this. So secret key of Alice and the secret key of Bob. Also called public key cryptography because it involves, let me guess, public keys. And the way to develop an intuition for this, what I really like is this model of a box. So you can think of a box with three states. So it can be either in state A, B, or C. Very good. And in A it's locked and in C it's locked, but B is the only state that's unlocked. And you can move from A to B or B to C or vice versa, but you can't move just from A to C. Okay. The idea with kind of public private key crypto is you can think of each key as one key will only move the box one direction. And the other key will move, sorry, not the box. I guess the box doesn't move, the key moves, but the one key, let's call it the public key will move the box, the lock state counterclockwise. So it's the left. And the other key will move the box state to the right. So this would be the public key of A and the secret key of A. So, how to use this? So let's say, I guess my name starts with A, so rather now it's gonna be my keys. So let's say there's this box in the middle of the room. If I have a public key, that means I've given you all the copy of my public key. So everyone has the public key of A. So, let's say that you come across the box in this room. It's on exam day, which we don't have exams, but if we had an exam day, and there is a, the box was locked in state C. Okay? You come in, you're the first person, well, if you're not the first person, because then other people have to trust you, you all come in at exactly the same time. You watch somebody take their public key of A, move the box from state C to state B, so unlock it, open it up, and there's a message in there that says, the exam is canceled today. Should you all go home or should you stay because it was a prank? You'd stay because you're risk adverse or because you trust the cryptography. How can the box get into state C? What was it? Only the person with the secret key can ever put the box into state C because that key's the only key that goes to the right. So all of you can never put the lock all the way to the right. So therefore, it's only the person that had that secret key, which should be me, so there you can trust that that message actually came from me, because I locked the box all the way with the right, none of you could have done that. And so you can trust that that message actually came from me. That was a message from me. Do you agree or disagree? Yeah, it's kind of crazy. We have two different keys, but based on the way the mechanisms work, you can really trust that. And the other way we can use this is if you had a very secret message that you wanted only to communicate to me, how would you do that with this scheme? Yeah, go through the states, what states? So this box is, the box is, let's say, is in state B. You can't put it in C. Yeah. Yeah, so then as soon as you do that, you know, anyone, as soon as you lock the box from state B to state A with your public key, you now know that nobody else can open that box except that they have the secret key. So you know that nobody else in the class is gonna snoop on that message. The only person that can unlock the box is me. And so that's how, so the interesting properties that you get from asymmetric cryptosystems is you can use the public key to encrypt messages that only I can read with my secret key. And I can make messages that you know only me could have made with my secret key. So I can make a message that is not encrypted because all of you can read it because you have my public key, like when I left that message in the box. So these are the crazy properties that you have here. So you get confidentiality in the sense that you can encrypt a message with the public key so that only the secret key can decrypt that message. You get non-repudiation, so I can make a message and you all know that I made that message. And the key thing that this requires is mathematical notions where it is easy to generate the public key and the secret key, but it is hard to generate the secret key given P. Why is that second part so important? It's true. Yeah, because everyone has the public key. If it was true to derive the secret key from the public key, then there's no point, right? This whole scheme falls apart because you all have the public key. In fact, the entire purpose of this thing requires that everyone has the public key. Okay, and another thing it requires is that each party keeps their private key private. Everybody knows the public key, so that's the important thing to remember. So both Alice and Bob know the public key, including the adversary who will probably use E for Eve, or you can think of as like evil, the eavesdropper, and everyone knows the public key of A and the public key of B. And so this is basically at a high level the way this works is that when we wanna send a message and encrypt it, so Alice wants to send a message to Bob that only Bob can read. What should Alice do? What keys should Alice use? Yeah, so we use like pseudo mathematical notation like this, right, so you have the message. So Alice takes Bob's public key. This stuff is actually also very easy to reason about in terms of like what information does Alice know? She has her public key, she has Bob's public key. Does she have Bob's secret key? No, it's in the name, it's secret. So it's really like a 50-50 shot of what to do here. But the idea being Alice can take the message, encrypt it with Bob's public key, then get Cypher text, and can send that Cypher text to everyone in the entire world, including Eve. The only person that can decrypt it is whoever has Bob's secret key, which should be Bob. Oh, that was almost bad. Okay, so Bob can take the secret key of Bob, decrypt the Cypher text, and get the message. So what does Bob know for certain at this point? That a message was addressed to him, and that it was somebody encrypted a message with Bob's public key. But does Bob know it came from Alice? No, that's an important thing, right? Just like when I, on that box on the table, if I use my secret key to open the box, I don't know who, I don't know which one of you sent that message. I just know somebody did. Somebody with my public key, but everyone should have my public key, so it could have literally come from anyone. We'll talk about other mechanisms of how that happens. Now, what does Eve know? So Eve knows Alice's public key, Bob's public key, Eve sees the message, or sorry, not the message, the Cypher text C, and so Eve can do nothing. So Eve can try to apply the public keys, but only Bob's secret key can decrypt the message. The only thing Eve knows is that somebody tried to send a message to Bob, but has no idea about the content of the message, doesn't even really know who did it. And so for non-repudiation, the other aspect that I mentioned, so Alice wants to make some statement that everyone knows this from Alice, so me saying the exams are canceled in the class. So how can Alice do that? What was that? She could take everyone's public key and encrypt a message to them that's computationally infeasible, yeah. So if she encrypts it with her secret key, now she has a Cypher text that can be read by who. Anyone with her public key, which is everyone, and the fact that it decrypts successfully with her public key means that it must have been encrypted by her private key, which means it must have come from Alice. So Alice takes her secret key, encrypts the message, gets Cypher text, she can broadcast that to the whole world, and then with Alice's public key, they can decrypt that Cypher text to get the message, and then now Bob knows for certain that Alice is the one who sent that message, and that Eve didn't spoof that message to pretend to be from Alice. Does Eve know the content of the message? Yeah, so this isn't hiding any information, right? Because again, Eve has Alice's public key, that key is public, so that Eve can also read the message, so Eve knows that Alice sent that message, but that's exactly what Alice wanted to do. Alice wanted to make a statement that everyone knows that is from Alice. Okay, so we can use these primitives, and we can actually get both of them together, which is, oh, we're almost there. Okay, one more, and then we'll break. So, what we'd really like is both of them. So I would like to maybe confidentially, Alice would like to send a message, M to Bob, so that he knows it's actually from Alice. So we can actually use, you can think of it like onions, this is how I think of it, these encryption layers, and so Alice can first take the message, encrypt it with her secret key, so now Bob would know that it came from Alice, and then pass that and encrypt that with Bob's public key, so that the only person who can outdo that layer is Bob. So this is why I think of it as layers. So this outer layer can only be undone by Bob's secret key, which only Bob can do that, so only Bob can look in, and then Bob can look inside here and decrypt that with Alice's public key to realize that the message came from Alice. Now, Alice and Bob are able to communicate to each other and verify that it actually came from them. So Bob does the opposite, right, on the onion, he's the only one that can do the secret key, and Bob knows for certain that Alice sent a message to Bob and that only Bob and Alice are the only people that know what this is, and Eve gets C and can do nothing with it because the outside it's encrypted with Bob's secret key. So this is crazy, this is like, and the super interesting thing is the two things we've been learning are tied together. It turns out, so like fast forward a bit, public key crypto is very slow, so oftentimes what happens is we use this to communicate a symmetric key, like an AES key, and then we use that to talk over AES to each other because now we've used this to bootstrap a secure communication channel between two parties, and this is what happens on the internet all the time with all your communication and data. So we'll get into like how this stuff works on Wednesday. Thank you.