 my name is Daniel Crowley. I work for spider labs. Let's just dive in. So one quick note, I'm a web application security guy. That's what my focus is. So this talk is going to be sort of centered around applying these concepts inside sort of a web application centric world. I'm not a cryptographer, but that's okay because these attacks can be used in such a way where you don't need to know about the underlying crypto. Although obviously if you know more about it, it's going to help you. Should you want to contact me? My contact information is going to be found here. And these slides should be on the CD as well. So groovy. So the presentation topic is about encryption or about cryptographic oracles. We're going to be talking a little bit about encryption oracles, decryption oracles, and padding oracles, which are generally used as decryption oracles and also as encryption oracles in certain circumstances. So like I said, little to no cryptographic knowledge is required. I'm going to be going over some basic terminology, some basic concepts. So if you don't know anything about crypto, well I'm kind of surprised you decided to show up at this talk, but thank you. But I'm going to try to cater to you as well. So good stuff. So let's talk about something that are not the presentation topic. So we're not talking about the oracle. We're not being harvested for energy by robot overlords, possibly. We're not talking about the company oracle. Fun fact, if you Google for any crypto word followed by oracle, you'll probably find oracle folks asking, oracle users asking how to encrypt their database. We're also not talking about Google, the Internet oracle. We're not talking about cryptographic gurus like Eddie Shamir. If you don't know who Shamir is, he's the S in RSA. Also awesome, but not the topic. We're not talking about new attacks on old crypto. I will be clarifying some details on the default encryption algorithm in cold fusion. But that's not exactly a new attack that's already known. I've never seen it made public. I wasn't able to find any public details on why Adobe says this is a weak cipher. No, stay away. We're also not going to be talking about how Patagon oracle attacks work. Now if you would like to know the presentation from Echo Party, patting oracles everywhere is a fantastic resource and it talks about the implementation of patting oracles as decryption oracles and using that against a couple different things, Java server faces, ASP.net, so groovy stuff. So I'm also going to drop a little bit of Ode on the DEF CON drinking game which is where you listen for buzzwords in presentations and then drink when you hear them. So APT iPad, APT China cyber war, cloud mobile botnet, cloud cloud, cyber twilight, APT Sun Tzu, RSA HB Gary, PCI Skeda in the cloud, cyber war, WOLSEC, APT China cyber war, Weaboo, WikiLeaks, mobile LOLSEC. So now that you're nice and primed for this talk, let's get into a primer on cryptographic terms. So it's very basic stuff here. So a cipher is just a system for mathematically scrambling data that you want to be hidden from certain parties. So a cipher is a system for scrambling and unscrambling data. The key is the one part that you keep secret. The key is the part that sort of missing variable that somebody needs to know in order to be able to unscramble the data. The initialization vector is used in a similar way but it's not always necessarily private. The idea of the initialization vector is so, it says a second key which doesn't necessarily need to be private although in a lot of cases it should be. The point of the initialization vector is so that when you encrypt the same thing with the same key, you can change up the initialization vector and the cipher text won't look the same. Now, getting on to that term, plain text and cipher text are the unencrypted and encrypted versions of the message, the human readable and unreadable. An encryption and decryption are turning plain text to cipher text and vice versa. So we can split the set of ciphers into stream and block ciphers. Now, if there are any cryptographers out there, maybe there's something else that I'm unaware of and I'm apologizing about that. But as for stream and block ciphers, with a block cipher you take a chunk of the data, you take the message in chunks and encrypt each of them one by one. So the key is used directly to transform the plain text into the cipher text. Whereas with stream ciphers, you're encrypting one character at a time, one byte at a time. And the key is used as a seed to a pseudo random number generator. It might be worth mentioning what a pseudo random number generator is. It generates numbers that look random but are not. For instance, you can use hashing algorithms as pseudo random number generators. So you can use MD5 and hash something repeatedly to generate a series of very predictable but random looking numbers. Things that are hard to predict but feed the same password in and iterate through MD5 1,000 times, you're still going to end up with the same hash, the same set of numbers. And then those numbers are used to transform the plain text into cipher text. So let's talk about some basic mistakes. One, using a keyless cipher. If you're using a keyless cipher, it is not secure unless it's totally private, unless nobody else knows how the algorithm works and even then it's probably not very secure. Also, reusing keys and initialization vectors, that's a bad idea and we'll see that shortly. It makes oracle attacks far more dangerous and it can also seriously weaken the integrity of stream ciphers. Web is an example of this. And leaking data from crypto operations, that sort of builds the foundation for oracle attacks. So I said the word oracle several times and now I'm going to give you a vague and generalized definition and then clarify a little bit. So an oracle is any system that takes in user input, processes it and gives the output. Now when we're talking about that in the sense of cryptography, we're talking about taking in plain text or cipher text and then usually encrypting or decrypting and leaking something about that operation. Whether that's the corresponding plain text to an input cipher text. Whether that's the cipher text to an input plain text. Whether it's info about the operation, maybe it's success or failure. Or maybe it could be a, just simply a sample from a pseudo random number generator or random number generator, which is referred to as a random oracle. We're not really talking about that, but thought I'd mention it. So now let's talk about how you can find oracles in web applications anyway. So first thing you're going to want to do is to try to identify input. Now when we're trying to identify oracles, it's easier for us to identify encrypted data. It's, you know, a lot easier to find than data that's going to be encrypted because how can we tell? So when we're looking for decryption oracles, we're going to look for cipher text being passed in as some sort of input. So you're going to want to look for all points of user input. Get post, URL, anything in the cookie field or in HTTP headers, which is a little bit rare, but can happen. And then identify those which might be encrypted. Usually when you have encrypted data, it spans a pretty wide character set, so it's not really possible to put that through the majority of systems and something might be interpreted as a merit character. So usually you have some sort of encoding scheme, whether that's URL encoding or base 64 encoding or just putting it to ASCII hex. So if you decode that data and it looks random, and there are some tools out there for doing entropy analysis to see, you know, how random is this. So another thing that you can do is modify the values. Sometimes this will generate, this will give you decryption related errors. The other thing is if you modify a value in the middle of some piece of cipher text, it might, you know, you might see some text, resulting text on the response that is fucked up beyond a certain point. So here's a little bit more on that. So when you're looking for the decrypted output, it might be reflected immediately to you in the HTTP response. Again, I'm still talking about web apps. Or it might be in an error. And this is something that's a little trickier. There's a lot of systems where the data might be processed, but it's never going to be given to the user, which is probably the proper way to do things. But some errors will leak information. I'm sure many of you are aware of that fact, but this is also important in the context of oracles. So it might be given a later response. So your data might be processed and then put somewhere where it's not going to be given back to you immediately. You need to find it somewhere else. It might be inferred from modified output. So maybe based on what the plain text is, you are getting different things. Might be stored and not shown. So encrypted data is often written to files or into databases. One example of where you might find an encryption oracle is through the use of an SQL injection flaw. So if you find an SQL injection flaw, you can find some piece of data that's encrypted in the database and then as long as you can add data or change data, let's say that passwords are being encrypted in the database, then you can change your password repeatedly and use the SQL injection flaw to look at what your password has become every time you change it. So this allows you to use it as a sort of encryption oracle. And I've actually done this before and we'll talk about a little bit more about the instance where I've seen that. So here's an example of where you might find a decryption oracle. So when novices are writing web applications, they frequently write one particular kind of file inclusion flaw in a script that's supposed to just make their lives easier. So essentially what they're doing is including a header, some page that gets passed in by user input, and then a footer so that they don't have to put the header in the footer and everything and they can change the header and footer for all the pages arbitrarily at any time they wish. So let's say that this developer found out, oh crap, I've got a file inclusion flaw. I know all sprinkle magic encryption dust on it. So you encrypt the input and that way you expect nobody is going to be able to, you know, do anything with this. Now, maybe. So let's assume that the errors are verbose. So if you take some ciphertext from somewhere else, let's say that they're using the same key and initialization vector and same cipher in some other place, you can take that ciphertext and plug it in here and if it's not going to point to some valid file, the application is going to respond by saying hey, I tried to open this path here and it didn't work. And that path will of course include the decrypted output from this operation. So that's an example of where you might find a decryption oracle. I put a picture of a kitten in here so that it wouldn't be just such a wall of text. It really has no relation whatsoever to the content. Thank you. I like the cat too. So again, we're looking for encrypted data when we're talking about encryption oracles but in this particular case, we're looking for it as output as opposed to as input. You'll frequently find this sort of thing in cookies and hidden variables in databases and file resident data. And then the next thing you're going to need to do is to determine the point of entry. So when you're looking at this encrypted output, usually it'll say, you know, it'll have some identifying information. Like maybe it'll be a variable that's in a hidden field and that variable will be named pet's name. So you really don't want to be exposing people's pet's name. It's very important. Okay, maybe not sensitive. But let's say it's pet's name. So you're going to look for where you can input a pet's name and then whatever. So you'll be, you can see, you can try modifying that and seeing if you get different cipher text. So some frequently encrypted data is client side state variables. So if you're keeping track of a user's session, certain things about their login, you want to store that on the session to keep it out of the client's hands. But once you start to experience more traffic, that's not really a scalable thing. You know, you start to store too much data, have too much session data. Actually there's an OOS page on a DOS attack involving creating large numbers of sessions when people are storing too much session data. So this causes its own problems. So some people will say, okay, well let's encrypt the data and then give it to the client and they'll pass it every time they are making a request. And that way we'll keep the state, we'll keep the session variables, but we won't have to hold onto them. So if you control part or all of that, you have an encryption oracle. So for instance, the view state in ASP.NET is frequently a partial encryption oracle. Now its usefulness is somewhat limited in that the key being used is only used for several other things inside ASP.NET. But I have seen people who just want to use one key for everything and will actually go to great lengths to use the machine key as the same key for encryption. So another frequently encrypted piece of data is passwords. Financial data is also frequently encrypted. Anything sensitive is often subject to encryption. So trying to modify these things and then look for any of those encrypted pieces of data changing is a good idea. But being encrypted is not enough, we also need to be able to manipulate it. So here's an example of where you might find an encryption oracle. Let's say that you have an authentication cookie. So this is a situation where you have session data that you want to store on the client, with the client encrypted and not store as session variables and hold down the server. So consider an authentication cookie that's the username concatenated with a colon, password hash, colon and time stamp. So we can't do any sort of replay attacks because of the time stamp. And we'll assume that the usernames can't include a colon character so we don't have delimiter injection, no field injection stuff. But this does mean that we have a partial encryption oracle. We can't control the whole thing but we control the username. If the only restriction is that we can't control the colon then we can do a lot of interesting things. We can encrypt a lot except we just can't control what goes at the end of it. Now there are definitely ways to get around this. Does anyone know what null byte injection is? Poison null byte. Okay so we've got some. The poison null byte is an issue where the null byte hex zero is seen as some frameworks. Seen by some frameworks is just another character and as others it's a string delimiter. So for instance when you're doing file inclusion attacks if you're tacking .htm onto the end of everything and thinking well this is fine. This is no problem. Everything's good here. They can only include HTML files. You put a null byte on there. Most web application frameworks will see that as just another character but once it gets passed back to the file system pretty much every operating system is going to truncate at the null byte because they're C based and the C is a language in which the null byte is a string delimiter. So it cuts off the end. So we can do some similar attacks here. So the fact that we can't control the end is actually just fine for a lot of attacks. So that's interesting. So we'll we can register with some username and log in and take a look at that cookie and we register with the username of whatever it is we want to encrypt. So groovy stuff there. So I wanted to mention padding oracles as well. So with a padding oracle the input has to be encrypted and it has to be with padded block cipher. With stream ciphers you're only encrypting one byte by one byte so the end of the cipher text sorry the end of the yeah the end of the cipher sorry the end of the plain text is just where the text ends and not where you've put some arbitrary marker. So it also has to be distinguishable when you've passed something in that has valid padding or invalid padding. And this is the essence of a padding oracle. Now I know that with a padding oracle you can do all sorts of crazy things and you can take over an old asp.net installation. But really all a padding oracle allows you to do is to tell whether or not the padding was actually valid. Now in the case of the cipher block chaining mode where the cipher text for each block in a block cipher is used as the initialization vector for the next one. So as to prevent repetitive plain text from producing repetitive cipher text you know to remove any sort of distinguishable patterns that might allow you to see that this is one this is this message and this is that message when they're encrypted. That's actually going to allow you to change the padding bytes and then change the corresponding bytes in the previous block until you get valid decryption again. So until you get to the point where the padding is valid again. So like I said I don't want to go too much into how padding oracle attacks work. But padding oracles can in that way be converted to decryption oracles. Now the interesting thing is Duong and Rizzo who presented the padding oracles everywhere presentation also talked about an attack where you can use this decryption oracle functionality of a padding oracle in this particular type of situation to encrypt data. Where you're just changing the data until you get the output that you really want. The way that it works it might be limited in that the first block is garbled. So if you end up finding a padding oracle and using it as an encryption oracle you can't control the first block. And again there are some situations where that's not a problem but it's something to be aware of. So let's talk a little bit more about exploiting these crypto oracles. So to convert one oracle into another most of this involves brute forcing. So we talked about padding oracles and using them to decrypt and encrypt data. Decryption oracles can be converted to encryption oracles. The idea is that you just brute force guess a whole bunch of cipher text until it decrypts to what you want it to. And that way you have the plain text you want and your input is really what you're looking for. Now since block ciphers do this several characters at a time you need to guess all of the characters in that block at the same time. So you need to keep doing that until you get it right. So that's a little bit more complex, a little bit more heavy on the queries. Whereas if you're talking about a stream cipher that's one byte at a time. So you can just guess even one bit at a time until you get exactly what you're looking for. So encryption oracles can be converted to decryption oracles in a very similar way. And again the same difference between the effectiveness when you're talking about stream and block ciphers applies. So we're going to talk about doing a little bit of crypto recon using oracles. So let's say you have an encryption oracle. If you encrypt the same plain text twice and it comes out to the same cipher text you know you have the same key, same initialization vector and a deterministic cipher being used to encrypt the data. So if the cipher texts are identical you know all of these things are true. You can also check for stream versus block ciphers. It's pretty easy to tell. So you can encrypt some piece of plain text and if the size is dependent on you know the size of the plain text divided by 8 or 16 or something like that then it's a block cipher and if it just grows and with the plain text no matter how many bytes you're tacking onto the end of it you know linear relationship you have a stream cipher. You can also check for ECB block mode. So this is a little bit different from CBC which I described earlier in that each block is independent of other blocks and are encrypted independently. So if you have repetitive plain text like 8 uppercase A's, 8 uppercase B's, 8 uppercase A's, 8 uppercase B's and that's your plain text. Your cipher text is going to have blocks 1 and 3 being identical and blocks 2 and 4 being identical. So you can see those patterns. So you can try to show that you can try to guess that behavior. You can try to get it to produce that behavior with an encryption oracle. And ECB you know you can obviously see how that's a problem because we can then take those blocks and rearrange them however we like. So we can also check for stream cipher feedback. So when you're working with a stream cipher sometimes the encryption of some particular bit whether or not it gets flipped is dependent on earlier bits in the plain text or the cipher text. What we can do to check on that is to encrypt some plain text and then modify the beginning of it and see if the rest gets screwed up. So let's talk about using oracles to attack some bad algorithms. So occasionally people try to write their own crypto and it doesn't work out too well. Unless you're a cryptographer and even then sometimes it doesn't work out so well. So let me show you some real homespun crypto that I've seen in the wild during a pen test. So here's a plain text hello and it's corresponding cipher text which is a bunch of what looks like gibberish. So I found an SQL injection flaw but it did not allow me to do anything but read data from the database. So I said okay well I'll get all the credentials from the database. Turns out the passwords were all encrypted and it was this bizarre looking stuff that doesn't you know doesn't really look like strong crypto. And so I thought okay well let's play with this. So the first thing I want to know if there's substitution. Are we switching characters for others? And that's definitely true but if we put in for uppercase a's we can see yeah there are no uppercase a's in that there is definitely substitution here. We can already start to see patterns in this as well. The plain text is repetitive the cipher text is repetitive as well. So the next thing we're looking for is if there's transposition. If characters are being switched around before or after the substitution occurs. So we'll submit AABB. And we see something similar to what we saw last time. And you can already start to see patterns in this very very quickly. So there doesn't seem to be any transposition. And we can see more patterns. The K also seems to be a delimiter. So one thing that you'll notice if you look at this there are a couple different you know you can have different lengths with these characters. So the K is just standing in to separate characters so that even with variable lengths for the cipher text version of different characters. Well let's move on. So it also doesn't seem to change on position. So next thing we do is we submit a variation on the last pattern. And we notice that you know more of our assumptions are proving to be true. That you know A like this ABE is uppercase B and LO is A. So this is pretty much exactly what we expected. The substitution doesn't seem to change no matter where the character is in the plain text. So next thing we'll do is just submit every character. And we get back the entire key. So we see what every character is substituted to. So this is a trivially weak cipher. And the oracle has helped us just totally destroy this cipher. So more bad algorithm stuff. Some people use ZOR to encrypt data. The funny thing about ZOR is that it has this weird property. So if we use an XOR operation between a plain text and its corresponding cipher text we get the key. So that's ugly. And you really don't want to be using ZOR. So another thing about ZOR, for some simple ciphers like ZOR, the encryption routine is the decryption routine. Thus, an encryption oracle is also a decryption oracle. Which means that I can encrypt or decrypt any data that you're using. Which essentially means that this encryption is totally useless as soon as an encryption oracle is introduced. And even before that actually. So please don't use ZOR. So now I'm going to do a demonstration. We're going to take a look at the default encryption algorithm in cold fusion. The CFMX compact algorithm. Now, I did a little bit of Googling on this and found that everyone said, hey, don't use this algorithm. This is weak. Adobe says this is the weakest cipher that we have. But, you know, for some reason they make it the default one that you use. So, okay. So I have, whoops, what? Oh, hey, lovely. So this is a simple script I wrote in cold fusion to take a plain text. And let me turn intercept off here for a moment. And it will return to me the cipher text of whatever I put in. So this is just a very contrived example of an encryption oracle. So here's something interesting. I've changed the end of this and we immediately see modification in the cipher text. And if I continue to delete characters here, you can see that this is chopping off more and more of the cipher text. Which means that this is a stream cipher. And also because we can see this changing, you know, but the prefix remains the same, that this is also a stream cipher. That this is also using the same key, same IV and a deterministic cipher. So next thing that we can do is change the beginning here and we can see that the end doesn't change. So we're not talking about any sort of feedback going on apparently. So this is interesting. Now, what this actually means, because stream cipher is essentially, once it comes down to it, are just crosswise or with a nice and complex key generation algorithm. And the only thing separating it from that in essence is this feedback. So not having feedback is really bad. So we're going to see why right about now. Now, here's something interesting. So can anybody tell me what X crosswise or with null is? X. So if we have a cipher that's essentially crosswise or and we put in null as the plain text, what are we going to get as the cipher text? The key, the key stream. So I'm going to get the first six bytes of the key stream here. And I'm going to copy this into Burp, which is a lovely tool. And decode this as base 64. So we have the first six bytes of the key stream here, which is great. So we're going to stick that into, oh no, I don't want that. All right. Lovely. Okay. So next thing we'll do here, we'll get a cipher text sample. What are you doing? So here's the encrypted version of the word Defcon. So let's copy that, put that into decoder. And now I'm going to do a little bit of Zor here. And we'll do a Zor a couple of these bytes together. So hex 42, crosswise or with hex 26. So we have a D and then an E. And we can go on and on like this and crosswise or this key stream with whatever cipher text we have and decrypt it. So groovy stuff. Because we already have an encryption oracle, that's nice. Now one funny thing is that if we, you know, like I said, since this comes down to essentially just crosswise or if we have plain text and corresponding cipher text, we can actually just crosswise or those two together and get the key stream anyway. So we don't even need an encryption oracle now that we've figured all this out. So in case the point hasn't been made clear yet, if you're using cold fusion, pick a different algorithm than the default. So now let's say that we don't have a shitty cipher. Let's say that we're using something like AES. And let's say we're even using it in a really, a really decent way. So the thing is people tend to reuse keys in IVs. So let's say that the only mistake we're making here is to reuse the same key in IV in multiple places. And a lot of people do that because they figure, well, if somebody can break in and figure out the key, then I, you know, what's the big deal? Like, so what? So what if I'm using it? It's the same stuff in different places. The other thing is that if developers don't think that you can mess with input, if they don't think that you can fiddle with it at all, they might not sanitize it. And the fact they probably won't sanitize it. And you would think that if you're using a message authentication code, which I won't go into explaining that, but essentially it provides protection against modification, you would think that this is tamper proof, that there is no way that this needs to be sanitized. So why bother? Why spend the cycles? So let's say that you have an encrypted password, mapped, in a cookie, like this auth cookie that we're talking about. And that's checked against the database on each request needing authentication. You find an encryption oracle somewhere else that allows you to encrypt arbitrary data. So you encrypt single quote or one equals one. Let's say it's just the password that's in this cookie. And then plug the resulting value into the cookie. Well, that's ugly. So let's take a look at this in action. So here we have a little login script that takes a username and a password. And this is what it looks like when you log in successfully. So let's take a look at this in the history here. This resolution is killing me. So this is ugly because it passes in the URL and that's terrible, but ignore that. Ignore me. Thank you. So you can see that this sets a username and password cookie. Now, if we stay on this page, if we just go back to it, you'll note two things. We're still logged in here, but it still shows us the login prompt. Now, something else that's interesting, the username field is populated. And if we look at the response, all we saw was the cookies. Hold on a second. Yeah, so all we see as for the parameters in the request are this encrypted username and password cookie. So this is actually decrypting the cookie and then sticking it in the output. So we've got a decryption oracle here, but it's not what we're talking about right now. Now, let's try some SQL injection here. Let's clear the cookies, try admin or double single quote equals double single quote, and we'll put the same thing in the password. So we take a look at the username here and notice that these single quotes are filtered out. They're removed. Now, people will generally filter the username, but not the password because it's going, you know, if it's going to be hashed and then stuck in a database, then who cares? The thing is though, but in this particular scenario, just a spoiler, this password parameter is not being filtered before it gets hashed. So we see that the username and password fields are the same and in the response, we get different ciphertext for the username and the password. So we can say to ourselves, maybe this password parameter is not being filtered. So let's copy that and use that as our username cookie as well. If it works, we should have SQL injection. Maybe. So we go back to the index and let's turn intercept on and burp so I can actually catch this as it goes. So we'll grab the password cookie which contains the SQL injection string encrypted and stick that into the username parameter. Hit forward. Oh, that's ugly. Well, that's what I get for doing the live demo, I guess. Let's try this again. Yeah, that's ugly. All right. Well, I'm not going to waste any more time on this live demo. It works. So we get logged in and it bypasses the SQL injection checks where we would not have been able to by simply putting the strings directly into the username or password field. So groovy stuff, I'm sorry it didn't work. So let me just log in with the valid credentials and I'll show you the next portion. So we have a couple different URLs here that we now have access to. And if we take a look at the input here, we have some sort of ciphertext being passed to a file parameter in getfiles.cfm. And I wish the resolution was a bit bigger because it would be easy to see that the beginning of the ciphertext. So here we see 9 slash f, 9 slash f. So these ciphertexts are starting with the same thing. Now, I wonder what would happen if we were to plug that data in here? So we get an error which decrypts that ciphertext for us. So we have another decryption oracle here. We also can encrypt arbitrary data so we can just stick anything into the password field and then grab the cookie and put it somewhere else. So let's do that. So what I'm going to do is to access a file in this test bed called secretdata.txt which is in the root. And so I'm going to put whole bunch of dot dot slash secretdata.txt and then we'll have this attack string as our password cookie. Everybody think good thoughts. Well, that's ugly as well. But you can see what I was trying to do here. Apparently I needed more dot dot slashes. But you can see that it's, you can see how this was working and you would have seen my secret love for Moxymarlin's bike. Also lulsec apt return on investment. Exactly. I encrypt whatever password I like and in the cookie I get the ciphertext for it. Yeah. It absolutely would. Yeah. The username field is another decryption oracle. And actually let's see that real quick. That's a demo I know will work. I say that now. Intercept on fire. Okay. So we'll take this password cookie and put that into the username field. Hit forward. And now we can see the decrypted version of that cipher text. Thanks for mentioning that by the way. I nearly forgot about that one. So that's a nice way to point out this next portion. Which is that with a decryption oracle any cipher text that uses that same key initialization vector cipher is subject to decryption if you can just find a decryption oracle. And maybe you've seen already that this is not too hard to do. It's a matter of making the right mistakes. So we already saw that. So that demo is done. So one last take home point that I want to make is that if you can find an encryption oracle and a decryption oracle, it doesn't matter, you know, what you're using. As long as keys and IVs are reused by the way that cryptography works, anything that's encrypted and decrypted with the same key IV cipher is going to be the plain text. So whatever cipher you're using, whatever key you're using, whatever padding you're using, whatever cipher mode you're using, it doesn't matter if you can find an encryption or decryption oracle. Anything with that same key IV and cipher is now as good as plain text. So what can you do? I don't want to make too many suggestions because like I said, not a cryptographer and the suggestion I might give you might be vulnerable to some other attack. Right now, I think there's a problem in that it's hard to do crypto right. Unless you're a cryptographer. I think keys are as nice because it just says, hey, you know, encrypt, decrypt, and you don't have to specify an algorithm and a padding mode and have to know what all that entails. But there's still missing. Obviously giving out information is bad. Leaking output from cryptographic operations is bad. Try not to give the output. Now, in certain circumstances like the example of the encrypted session data, that's ugly and there's not really a great way that you can do that right. One thing that you can do however is to use a different IV. Don't reuse keys and IVs if you can help it. So that's, you know, that's good stuff. Try to suppress any indication of success or failure if you can. Again, that's not really terribly plausible in a lot of situations. And timing if you really want to go the extra mile, try to suppress that. But that's I think more trouble than it's worth. It's worth noting however the timing information can give away the success or failure of an operation. Also authenticating your crypto is a good idea. Encryption is good but if people can fiddle around with the message and end up with a valid output, a valid cipher text, it will still be subject to whatever operation it was going through before. And in some cases it doesn't matter what the plain text actually is. So for instance if you have an encrypted value which represents the amount of money you have in your bank account, your chances are pretty good of getting something better than zero. So if you're at zero and you just mess around with the cipher text and you can produce a valid cipher text, it's probably better than zero. So authentication is good because it doesn't, it prevents people from messing with that at least to some degree. Also you want to encrypt and then MAC. If you MAC and then encrypt it still allows for padding oracle attacks. So that's it. If you have any questions, I'd like you to come to the Track 2 QA room and ask them there. So no questions right now.