 Hey everybody, this is Brian. Welcome to the 153rd cute tutorial with C++ Muguay programming. I better double check that. Yeah, 153. Sorry, it's been a long day. So we're going to continue on our open SSL wrapper. And today what we're going to begin down is the AES or Advanced Cription Standard, also known as the Rindel block cipher. Okay, this is probably going to have to be split up into maybe two videos depending on how my patience with this weathers and how long I can actually talk. My throat's really scratchy. Also, this is a fairly complex topic. So if you know what AES is, you can effectively skip through probably the next minute of me explaining. But basically AES or Advanced Cription Standard was basically developed to trump all of the other encryption standards. This is the strongest thing we have out there. If something stronger comes out, it'll effectively date this video. But effectively, jeez, I am tired. Sorry. Basically, AES has different modes. And what we're going to be focusing on is called the AES 256 bit cipher block chaining mode. What that means is it takes a block of data, as you can see in this little graphic here. And it'll actually substitute bytes and move things around. It does that in blocks. And sometimes each block will affect the next block behind it. And there's different ways of doing this. So as you can imagine, this is a lot like taking a bag of jelly beans, opening it up and spilling it on the floor and shuffling it all around, and then saying, okay, it's encrypted. Now to decrypt that, you have to put everything back the way it was. So to do that, everything has to line up perfectly. And if it doesn't, you're going to get just garbage back. So that being said, this is a military grade encryption standard. So is RSA, by the way. But AES is probably used more widely. Also, not every implementation of AES matches. For example, if you use the .NET version of AES, it may not be compatible with the Java version of AES. Take the bag of jelly beans analogy. If everything doesn't line up, it's not going to be exactly the way it was. In practice, it should be. You'll hear people say, well, AES is AES, yes. But every vendor's implementation of AES may be slightly different. That's part of the reason why we're focusing on OpenSSL, because it has, I daresay, the widest installation base as far as what code is actually running under the hood. Almost all the major programs are using OpenSSL under the hood. A lot of novice programmers will say, you know what, I'm going to write my own AES standard. Don't do that. The reason why you don't do that is exactly what we just said, is not every vendor's implementation is going to match. So if you write your own and you use it, and it has some bug where it works with .NET but not Java, guess what, you're going to have that bug later on down the road. Also, things like OpenSSL, they have been vetted. You've had thousands of people go through the code and test it, and you've got all that technology right there waiting for you. All right, I will get off my soapbox. Where are we left off? Where did we leave off? Okay, we got it so that we can actually test RSA. Let's give us a good build and run. And there's RSA encryption at work here. We're going to load the keys, we've got the string, encrypt the string, and decrypt the string. So we know RSA is working. Now remember, the ultimate goal here is to encrypt data with AES, which we're going to write that code, but the AES key has to be kept secret at all times. So we're going to use RSA that we created in the last video to actually encrypt the AES key. That, depending on time, may be another video. I'm doing horrible for time because I'm talking. So enough talking, let's start writing code. So we're going to start with the simple functions first here. And we're just going to say, Q file, I just cannot wait for the weekend. I don't know about you guys. It's Thursday afternoon and I'm mentally just like, I don't want to even do anything. I had to like talk myself even doing this tutorial. I just want to like play video games and drink alcohol and not care. But I'm actually addicted to writing code. I miss it so much. I used to do it professionally and not anymore. I manage people. So it's not the same. Let me tell you, I've done a little bit of everything in life and it's definitely not the same. In case somebody wants to know, why did I stop writing code? The geographic area where I live in, I live in Michigan. All the coding jobs, I shouldn't say all. Most of the coding jobs dried up. There just aren't many anymore. The ones that are there are not very well paid. They horrible benefits. They suck. All right. So write file. This simple function is just literally going to take the contents of a byte away and write it out to disk. It's just a helper function similar to read file. Random bytes. Let me see here. Random bytes is actually something we're going to need. So let's flesh this out. All we're going to do is we are going to call the RS, which is the open SSL ran bytes function and then it's just going to return some data back. So I'm going to say unsigned. So, yeah, speaking of the weekend, I kind of want to play some video games this weekend. I've been playing Eve online and I've been playing Overwatch by Blizzard. Both are just really fun. So what we're doing here is we're getting an array of unsigned characters and we're going to just pump that over to ran bytes. Who's going to fill that array with, well, you guessed it, random bytes. We're going to say Q byte array buffer. I don't know why I call everything buffer. It's not really a buffer. Old habits die hard, I guess. All right. So we're going to do reinterpret cast, pointer to care and the array. Sometimes I miss Python. Some of this syntax gets kind of crazy. So I may go back to doing Python tutorials in a little bit. I'm not sure. I definitely need to get back to doing Yi tutorials. I kind of left off on that. All right. So what this really does is it just says create an array, give the array to the function, open SSL in the background. We'll fill that with random bytes using a random number generator. And then we're just going to reinterpret cast that back into a Q byte array and return it. This is kind of one of the main headaches of working with Qt. You don't really have to do this, but a lot of times if you're going to build a wrapper or a Q class, you really should, well, essentially just, you know, convert things back and forth, because a lot of times people aren't going to convert them correctly. All right. So let's go in here and I'm looking at my notes real quick. All right. So first thing we're going to do is let's encrypt with AES. All right. Let's encrypt with AES. I had to pause the video for a second. Something. So this is the moment you've been waiting for. How do we encrypt something with AES? Well, we have something a little different here. We have a passphrase, which think of it as a password. I don't like calling it a password because it's really not a password. And then we have the data. And notice how those are both Q byte arrays. So first thing we need to do is generate what's called a salt. So we're going to say Q byte array. Let's call this M salt. Why I call it M salt? I have no idea. And then we're just going to say random bytes. And then we want the salt size. If you're wondering where I got salt size from because I'm not a big fan of magic numbers, it is actually defined up here in the header. Salt size is 8 bytes. So what a salt does is let's say you encrypt data and that data has the same password. What the salt does is randomize it. Meaning if you have the same password and you have the same algorithm, that data is going to come out exactly the same every single time. And from that you can actually defer the password. It's actually been done. It's a known attack. So what a salt does is it randomizes that. So you can have the same data, the same password, but the salt's different and the salt randomizes everything. So all right. We're going to say int rounds equal one. This is the number of rounds that we're actually going to do. And then we're going to say unsigned. Oops. Care. And we need what's called a key. And this is going to be key size. Once again, that's defined in the header. We're going to say unsigned care IV. And I'll explain this here in just a second. So you have what's called a key. Well, actually I'll explain it now. You have what's called a key and an initialization vector. And the key and IV are used in conjunction with the salt to actually encrypt the data. So it's, there are three things you really need to encrypt. You have salt, key and initialization vector. So one of the first things we're going to have to do is convert this passphrase into a usual key and initialization vector. Hmm. I had to pause it again. Sorry. I really hope pausing doesn't screw up this video. So let's say, where were we? Oh yeah. Now we are going to say cost unsigned care. And this is probably a waste of time doing this, but this is just how I did it. So I think originally I, I did it where you could actually hand at the salt. I think that's why I did it this way. So feel free to just, you know, fill it out as a constant unsigned care to begin with. But we're going to do that. And then we're going to say, do the magic of copy and paste because I'm not a big fan of writing code. So we're going to get an unsigned care array of the salt and the password. Now comes the part where we actually have to convert this. And we're going to say int i equals evp. Now anytime you're an open SSL and you see something that starts with evp, we're calling what's called an envelope function. So we're not writing the code ourselves. We're just calling a function inside of open SSL that does all this complex stuff for us. It's a huge time saver. So we're going to call envelope bytes to key. And in bytes to key, we need to actually give it the cipher that we're using. So we're going to say evp, move my mouse so you can actually see that. Evp, excuse me, aes. And then we have all of these to choose from. So we are going to do aes, 256 bit cipher block chaining. And that function actually returns what we need. And then we're going to say evp shot one. If you don't know what shot one is, it is a hashing function. It's a one-way hash. A hash will take an array of data and turn it down into what's called a hash or a unique identifier, I should say. I shouldn't call it unique because there's nothing really too unique about it. But it takes a large volume of data. Think of like a DVD full of data and it'll turn it down into a string but like what, 128 characters or something like that. And it represents that data in some. So if you change that data, the hash will change as well. Okay, now we need the salt and the password that we did. And we're going to say passphrase.length and then the number of rounds. This is important. We're seeing one up here. Because that is what the OpenSSL command line does. It does one round, but if you want it stronger, by all means increase the number of rounds. Just know that when you increase the number of rounds, it will also increase the amount of time it takes to do this. And it can be a little intensive, especially if you do this on like a mobile device or a slow computer. All right, so now that we have called that function, now let's give this a good bill just to make sure I didn't goof anything up. Okay, good. Now that we've called this, we need to check this return value and make sure that we didn't goof something up. So we're going to say, if, whoops, I'm not equal, key size, then we are going to say, and I'm just going to try and shave a little bit of time here by copying and pasting for my notes. We're just going to say, whoops, Q critical, you know, EVP, byte to keys, error, and then the error string, and then we're just going to return a blank array because we're returning an array out of this. So we're doing some very, very basic error handling here. Now, what this does is it takes your passphrase and it shoves it down into here and it turns your passphrase into a key and IV for you. You see there's key and IV using the number of rounds. So this is going to do it one time, but let's say we had 200 rounds, 200 times, and that can get very time consuming and process or intensive. You do this function instead of just giving it a passphrase or a password, if you will, because this will generate what's called a secure key. You don't want to say, you know, my password is Mary or Bob or cat or dog or password because it's very insecure. What you want to do is have open SSL, use this bytes to key to convert it into what's called a secure key. That way it's much more secure than just giving it, you know, my password is password. All right, I hope that made sense. EVP, now we're going to continue on. Cypher, whoops, we're going to get Cypher. I think that's Cypher contacts, we're going to call it EN. And then we're going to say EVP Cypher got lost there for a minute. There we go. We want CTX in it. So we're going to initialize that bad boy. If you're wondering what that does, I have no idea. Be really honest with you, I don't know what it does under the hood. I just know you have to initialize it. I think what's happening, don't quote me here, is that you're getting a Cypher context and then you're initializing that context and some magic happens in open SSL land under the hood. Not a big fan of magic happening, but we need it to happen. Now we're going to say if not EVP encrypt, if not encrypt init ex, there we go. And we're going to give it our EN, EVP underscore AES, 256. Cypher block chaining is our current hash, gCypher that we're using. We're going to give it a null for the implementation and we're going to give it the key and the IV here. Alright, so as I clear my throat, what just happened there? Let me, for the sake of time here, copy and paste our little air handling in here. What we're doing is we're saying envelope encrypt init and then we're saying our context, our Cypher and then the key and the IV. So we're initializing the crypto engine under the hood and saying, hey, put the key and the ignition, put the car on, get ready to go somewhere because we're going to start encrypting. Now we're going to actually do the encryption part. I'm going to say care, care. I don't know if the video is picking it up but I have Pandora playing in the background. This is like a really good song in the background so I'm a little distracted, sorry. Alright, so we've got our input, we've got our out and we've got our len. Three things that we're going to need for this. So I'm going to say int C len equal len plus AES block size, there we go. Now we're going to do a little bit of memory allocation here. I really got to think about getting two monitors because these notes are like uber small. So we're going to have to remember to unallocate that by the way. Now we've got that and this is, the Cypher text is basically a chunk of memory that we're going to put the encrypted data into. We're going to take this and we're going to say if not EVP and the EX. There we go. It seems like I'm distracted because I actually am trying to remember what exactly we're doing here. If I remember from what I read we're basically double checking to make sure that the crypto engine is started and there's no problems here. The reason we do that is because if an accident happened under the hood in open SSL we'd have no way of knowing without actually checking for it. So all right, let's do this now. If we've gotten this far we can actually go ahead and attempt to encrypt the data. Let me actually scroll down a little bit so this is up in the screen so you can see it. So we're going to call envelope, encrypt update and we want to give it the en, not enk en, Cypher text, C underscore lin and we want to give it the unsigned care of input and the length. There we go. That was a lot to type. Let's give this a build and make sure nothing's goofed up here. Good. When we do some of these longer tutorials I get a little bit nervous that something's goofed up. Like I've had to pause the video a few times and in the past it's kind of screwed the video up and sometimes I'll get like 20, 30 minutes into writing the code and then realize there was some fundamental error in all the first two minutes in. All right, so we've got, let's backtrack here and go to the top, make sure we're all on the same page. Got our salt, our key, our IV. We've got our unsigned care that we're going to dump these into. We are converting the passphrase into a secure key and IV, if you will. And then we're making sure that we got the right size. We're getting an encryption context. We're making sure the crypto engine starts, or I should say we're starting the crypto engine, doing a couple things, allocating some memory, making sure the crypto engine started and then we're going to actually, you guessed it, voila, do the encryption and this function right here will take it and basically say, okay, throw it right in there and that is the memory buffer that we've allocated. Now that we've got that, we need to actually do something with it but before we can do it, and this is where it gets a little weird, I should say weird to me, some of you are probably used to this. We need to actually finalize. We need to tell OpenSSL, hey, we're done. And I should say word of caution. This, what we're writing, may not be suitable for large, huge files. You may have to do this on a loop. I haven't really tested with humongous files. When I say huge, I'm talking like four or 500 meg kind of things. This should work fine for anything under 500k or a meg easily. Should. There we go. So there's our encrypt final. We're going to give it our context, en, we're going to say ciphertext plus the clin or the length here and we're going to give it a... So we've got a lot of crud going on here as I like to call it. So really all we're doing is we're saying, hey, tell OpenSSL we're done encrypting. I'm going to put a note here. You get into massive files like gigs and size. You're not going to want to throw everything in memory like we're doing. You're going to want to read it in chunks, hence cipher block chaining. You read it in blocks and then you write it in blocks, things of that nature. And I may in the future rewrite this so that it does like massive large files. I just haven't had time. I wanted to get through this part of it. So we want to get the actual length of the data. We want to say out equal and then we're going to say evp cipher clean up because we want to clean up behind ourselves a little bit here, right? Whoops, en. And we want to say cubite array finished and this is just where we're going to convert it. We're going to say finished. Whoops. That's the type of day I had. I can't do that. Now, I can't take credit for this. I actually looked this up. I wish I had the link. I'd love to give them credit. There was someone else out there that was working on this and they figured this out. You got to have this salted underscore and then actually append the salt. Now, I know you're probably thinking, well, isn't that dangerous to put the salt in there? No. No, it's not dangerous at all. You actually need it to decrypt it. The reason being the salt is absolutely worthless without the key and the initialization vector. It does nothing. Actually, the initialization vector, you can give away too. It's the key that you have to keep secret. So out and lend, return, finished. Let's give this a good build. All right. So that in totality should actually encrypt our data here. So let's go in here and let's copy and paste this just because I'm lazy. Test AES. Let's say testing AES. All right. We don't need public or private key. We do need the wrapper. We don't need that. We do need our plain text here. We're not going to decrypt yet because we haven't gotten that far and we don't need to free the keys here. And what we do need to do is encrypt AES. We've got our passphrase, which let me see what I use for passphrase in my test here. I'm probably knowing me just something really stupid. Yeah, it was something really stupid. All right. Are you ready for this? Passphrase was password. Yeah. My super strong password. We're going to give it a byte array. So we're going to say dot to Latin 1. There we go. And we're just going to test this out here. So let's comment out this test RSA. Give us a build. And let's see here. The man in black fled through the desert and the gunslinger followed and there is our super strong encrypted. Now the problem with that is we don't really know. Well, we know that it did something to it. Let's not do the... Where is it? Where is it? Yeah, let's not do the base 64 here. We can tell just by doing this that we've jumbled some bytes around. It's no longer readable text. You can see it's salted and then the salt is the first eight bytes. I think the initialization vector is actually stored in there somewhere. No, actually, I'm sorry. It's not stored in there because we derived the key. So we have effectively encrypted. Now we have to see if we can actually, well, unencrypt this because encryption is kind of pointless if you can't unencrypt it, right? So let's try and figure that out. Fortunately, encryption and decryption are very similar, so we can probably save a good chunk of time by doing some copy and pasting. However, if I remember correctly, we did a memory allocation here that we should probably fix. I'm having one of those days where I'm old and blind. So where's my malloc? There it is. All right. So as I do actually read your guys' comments and let me pull that up here. On the 152, I did this whole tutorial and shouldn't you call free every time you call malloc? Yes, you're absolutely right. We totally should. So let's fix that code real quick. All right. So what do we do? Cypher text need to be cleared up here. Let's do that. And let me find it. Let's see here. Buffer. Did we not even use buffer? Let's try this. Actually, let's do Qbyte refinished. Very sorry. It's been a long day. I'm sure you understand. If not, oh well. Just deal with it. It's been a long day. All right. So we're going to free this up here and we're going to free Cypher text. All right. We're going to reincorporate cast to care. I think we already did that. Yeah, it is a care pointer. We'll do it here anyways. Bam. So what reinterpret cast is essentially doing is making a copy of that. One painful lesson that I learned was that when you take Qbyte array and you give it a care pointer, what happens is Qbyte array doesn't actually copy the contents of that array. It just gives it the pointer. So when I was playing around with this off-camera, I deleted that pointer and guess what? Boom. I got garbage data. So we may have to come back and visit this. Just FYI. I'm kind of fixing mistakes on the fly here. Yeah, and I've already got an issue. Let's see here result win. Let's call this buffer not finish. See, in the perfect world, if I had time, I would have totally done this before I started the video. Let's not call that buffer. Let's encrypt it. There we go. Let's give this a good run. Well, sure looks encrypted to me. And OpenSSL is not a forgiving encryption engine. And what I mean by that is let me take that base 64 out of there. You see how it is, you know, all encrypted. We don't know for sure because we haven't built the decrypt function if we actually encrypted it correctly. Because we're not getting errors back from OpenSSL, I'm going to assume it's correct. But not all the time will OpenSSL actually give you an error message back. Sometimes it'll just give you garbage data. And that's what I mean by it's not forgiving. Some encryption engines, when it fails to encrypt, will literally hand you back the plain text. And your application will start leaking, you know, plain text all over the place, which is very, very bad. So OpenSSL kind of solves that problem by saying, well, you know what, I'm just going to give you garbage data. So, all right, now hopefully this next part will go a little bit faster. If not, this will be a very long video and I apologize. We can kind of do a little grunt work here. So we're going to say, Q byte array, M salt. And what we need to do here is we need to actually get the salt from the data. So we're going to say, if Q string, data.mid, and we're going to say starting position 8, or starting position 0, length of 8. So if it starts with literally the string salted, then we know that this has been well salted. And then we can extract the salt out of there. Because remember the first 8 bytes of that are going to be the word salted followed by the actual salt. So then we have to say starting position of 8 with 8 bytes. And then the actual data equals, and we're going to make a copy of that. I don't like doing that, but we're just going to do it. Starting position 16. So on the 16th byte is where the data actually starts. Otherwise, we are going to give ourselves a warning and set the salt as random bytes, which will effectively negate our encryption. In case you're wondering, yes, this will actually screw up our encryption. In a production application, you would not do that. You would simply hard exit and say, hey, fail to get the salt. But I'm going to give you the opportunity here in case you're wondering how to do that. You just give it the salt here internally. I think my daughter just called me. I wonder what the kiddo wants here. So while I'm looking at my notes and making sure my kid didn't get into a car accident or something, no, she's just chatting. We'll continue on. And then the rest of this is pretty much going to be the same. I may actually just copy and paste around on my notes to save a little bit of time here. So we're going to have number of rounds. We're going to have our character, or our character g's our key, our initialization vector, our unsigned version of the salt and the password. I don't like calling it password because it's really not a password. And then same thing, we're going to do our bytes to key here. So let me go up here. It's literally the exact same code where we're just saying bytes to key and then give it everything that we need. That way we're generating the same key, the same initialization vector, hopefully using the same salt. So everything up to this point should be dead on. Sometimes developers will put in little checks and balances to make sure. Other times they just won't. And if they don't, you're kind of at the mercy of the forgiveness of the OpenSSL library, which is not very forgiving as we've kind of deduced. This is where it's going to deviate a little bit here. We're going to say DE for decryption instead of encryption. And we're going to say EVP, Cypher, CTX in it. And we're going to initialize the decryptor. In case you're wondering, you really could have named that EN just like we did up here. It doesn't really matter. All right. So now we have to actually start up the decryption here. So we're going to say if not EVP underscore decryptinit EX, sorry. And we're going to give it the DE. I ran two miles today. I shouldn't have done that. I'm just whipped. I mean, on top of work, I'm just like, you ever have one of those days where you just want to go home and crank up the music and listen to something good and drink like a whole bottle of wine and not go to work the next day. Just call in unemployed. Work wasn't really that bad, but you get the point, right? EV, all right, good. So what we're doing here is we're initializing, you guessed it, the decryption. We're going to just give ourselves a little bit of error handling here. Why isn't that all in one like this? That should be all in one. I have failed. I have failed you, my friends. I'm very sorry. All right, there we go. I want to give this a good build. Make sure we haven't screwed anything up so far. There's really two types of programmers in the world. There's the first type that will write code for 12 hours straight and then attempt to build and debug. And then there's people like me that will do incremental builds and then go from there. I'm not a big fan of just trying to figure it out on the fly. So let's see here. Where am I? I'm out of notes. There we are. And in case you're wondering, yes, there is probably a much easier way of doing all of what I'm doing. There's probably a lot less of conversion that needs to be done. This is just what I've done, how I got it to work and slapped it together for tutorial. This is not what I would consider production grade code by any means. It could definitely use some love. I may actually make like a professional level wrapper for this because I've actually put a lot of time into learning open SSL and other size. All right. So int plin equal lin comma flin. If you were wondering, I'm just setting these to zero here. Now we are going to allocate a little bit here. Oh, come on, stomach. I wasn't hungry until I started making this and now I'm bordering on dying because I haven't eaten. So now we're going to memory allocate here. Signed care star mallock. All right. You know, there's some, yeah, I watch some people on YouTube and some of their tutorials and I'm just like awestruck and how they can, they can do like these hour long videos and they have like no mistakes. I'm just like every other sentence that comes out of my mouth is oops, oops, oops. You probably turn that into like dubstep or something. All right. So if all right. So we're going to say if not EVP and we want to do decrypt update and here we're going to just give it the decryptor context. We're going to say plain text, the plain text length and unsigned care star, the input. That's like so annoying that it's like right in front of where I'm trying to type and then the actual length. I had to figure out how to turn that off in the settings. If it's annoying me, I can imagine if you're sitting through watching this, it's annoying you. All right. So we will do the magic copy and paste put that in there. Give it a good incremental build. All right. So essentially what we've done here is we have said, you know, decrypt update. So once again, not an expert in open SSL, but I believe you may have to do this multiple times and I'll put a question mark because I'm not a thousand percent sure about that. Just bear that in mind that if you're like, Hey, Brian taught me this really cool thing and I'm going to encrypt this entire DVD and it suddenly doesn't work. That's probably why right there. We're pretty much just going over concepts, not professional grade code because well, you know, like I said, I'm ready for the weekend. So we're going to do our decrypt final EX. I mean, we're going to do our last round of encryption here. Very important. plain text plus the plain text length and a reference to the final length. There we go. I got to start bringing like orange juice or something. When I do these long videos, my throat gets really dry on top of already being dry and scratchy from allergy season. All right. So then Lynn P Lynn plus the final length. Yes. Whenever you encrypt something, it actually gets bigger. Always remember that. And somebody out there is probably going, Brian, remember you did a memory allocation. So yes, I know we're going to get to that, but I want to put this in here because it's the way it was in my notes that I was doing for the tutorial and then we'll actually kind of fix it on the fly because I'm just kind of like that today. So EVP, Cypher CTX cleanup because we want to clean up after ourselves here. And somebody asked me in an email, they said, Brian, if you love programming so much, why don't you program professionally anymore? And it's just like I was saying, strictly money. This region programming jobs don't pay much. They're outsourced quite a bit. And they're just generally with companies I don't want to work with. Let's just put it that way. All right. So a little note here. We're going to come back and well, you know what? Let's just do it. Let's give it a build. There's no sense in doing it wrong. All right. So let's kind of do, let's grab this guy right here. All right. So what we want to do here is we want to, we're going to want to free that plain text, right? Because we did that in a memory allocation. That's a buffer sitting out in memory. We don't want to sit there and clog up our memory. So let's say decrypted plain text. And then we're going to return. Well, we don't want to do that. That would be bad. See, this is what I mean by this gets a little confusing here. If we would have freed it before we did it, we would have just gotten whatever random garbage was at that memory location, which would have been very bad. All right. So then return. Let's do it down here. And I'll clean all this up in a minute. I just, like I said, if something goes horribly wrong, I want to be able to jump back the way my notes are. All right. So, which means we can effectively get rid of this. Let's go in here and let's say decrypted. And we want to decrypt AES. And we want to give it the passphrase. Now remember, this passphrase has to be like top secret, which is probably going to be the next video where we're going to encrypt it with RSA and build this whole big wad of data here. And with any luck, let's give this a solid build. And we should. All right. The man in black fled through the desert. And the gunslinger followed. And then the encrypted data. And then the decrypted data back out. So that was a lot of typing. And we should do some cleanup real quick. So we're not done. I want to explain a few things. First and foremost, what do you do if this works? This works? This does not work. Meaning you just get random crap back. It doesn't decrypt. Check your key. That's the first thing. Check this passphrase. Make sure you're sending the exact same thing back. Because a lot of times what people will do is they'll store it on disk. Very bad. Don't do that. But they'll store it on disk. And then the way they write it to disk encodes it a certain way. Remember, if you add the slightest little change, you know, whether it's a little extra bite or you remove a bite or you, you know, whatever, it's going to totally jack that up. So note to self, especially if you're writing, write that out as binary, not as plain text. And definitely mind your encodings. Other things we should go back in here. Let's just play around with this a little bit. Let me get rid of that. Where did I declare out at? Somebody? Anybody? Here. That's where I declared that. Give it a build. Make sure nothing explodes. We're about out, set, but not used. So that's up in our encrypt. Yeah, that's in the encrypt. We're just going to clean this up. That way I can throw it up there. On my website. Give that another build. And run. Make sure everything still goes. And I'm Uber paranoid. So I actually like to do a rebuild right before I post this up on my website. Because I've had it kind of bite me before where it didn't work. So there we go. There is the basics of AES encryption and decryption. A lot of typing. Sorry, my voice is getting super scratchy here. I'm going to take out a lot of this common stuff out because you won't need to see it. I'm going to throw it up on my website. Voidrums.com. And this is where my friends always yell at me. They say, Brian, sell yourself. This site is 100% funded by your donations. So if you have millions of dollars, please donate. That way I can continue this. But if you're a starving college student, don't worry about it. For the source code for this and other tutorials, go to the tutorials tab. And then look up cute. I'm sure you probably know this by now. And go way, way, way, way, way, way at the end. I'm actually going to redo this whole website. I'm sick of it. And it'll be right here. It'll be C++ Cute 153. The next tutorial, we're going to kind of combine the two where I show you how to encrypt the AES key using RSA and how to securely hand things off, meaning what to give people, what not to give people. And we'll probably write a couple of test functions just to see how this thing works under the hood. But I'm tired. I'm going to probably go grab some dinner and a beer because it's been a beer kind of day. What's your favorite beer? Mine's Guinness. So let me know in the comments.