 Our next speaker is Guy. I'm not gonna try to pronounce his last name. He told me not to do that. Okay. He's besides Salaviv Chairman and CTF Lead, also a public speaker and recipient of the Cisco Black Belt Security Ninja. That's nice. We've nearly 20 years of experience in cybersecurity industry, currently providing security services, focusing on OS, hardening, crypto, AI, and reverse engineering, and he's going to talk about crypto failures and how to avoid them. Give him a round of applause, please. Thank you very much. Can you hear me in the back? Cause I tend to walk about, so I'll take the hand mic, but if not, I'll just speak very loudly. Okay, so welcome to my talk about crypto failures. Before I begin, I just want to say one thing. I'm not dissing anyone who's actually developing and using crypto libraries, but I do want to point out several failures that I have seen happen over and over again, and try to give you those patterns and some tools and some ideas of what to do when you encounter such issues or such things. But I also wanted to make this talk, let's say, entertaining and show you a couple of, well, at least for me and probably for others, pretty funny failures. Some of them are of very large extent. So, I said so, okay. This should work. Okay, so as I was so kindly introduced, I'm besides Tel Aviv chairman, I also do the CTF. I invite you all to come to us to Sunny Tel Aviv in June for a pretty nice conference. I'm here and I've been here for quite a while. I've seen a couple of different things in different areas. I've managed a cryptographer, I've managed developers, I've managed reverse engineers, and some patterns tend to emerge again and again. So, I want to focus on that. The first thing and probably the most important thing is crypto is math, and that kind of scares a lot of people, and I'll try to give you like a first introductory idea into what cryptography actually is without going into the math, because obviously most people don't really care. But more than that, I want you to get like a very, at least fundamental understanding of what you should expect, and when you don't see that, it should light a red flag. So I'll give you a couple of examples. So you probably are already familiar with the CIA, confidentiality, integrity, and availability concepts from other perspectives. This is also true for cryptography. So when we are saying confidentiality and talking about cryptography, it means we want to keep things secret. We want to have some sort of method, some sort of idea or function that if we know the secret, then we will know what this payload contains, and if no one else knows that secret, nobody else can know what this secret contains. Identity comes to the same thing. We want to make sure that if someone sends us the message, we can verify that we got the message from that person or that system and not from someone else. Fishing comes to mind. The third one is authenticity. Can we trust that nobody touched that message or modified that message? Did we actually get the same message that the sender sent us, or was somebody messing around with it along the way? This is kind of a personal point for me, but I'm not ashamed to mention it. One of the teams I led when I was at Cisco was in charge of an area called supply chain security. So I was the very happy owner of that specific area of responsibility when Snowden releases documents. If you remember the nice image of NSA intercepting Cisco equipment and doing supply chain attacks, that was fun. And my point is that authenticity is important. When you're dealing with a product, with a vendor, with a library, you want to make sure that what you're getting is what actually the developer or the system actually intended you to receive. If you remember the NPM dependency issue from about a year ago, more or less, somebody decided that he doesn't like the left-aligned string to maintain that anymore. He kind of dropped that, everything broke. Somebody put some malicious code or stuff like that into the dependencies of NPM, and now everybody got the same kind of libraries along the way. This is something that you need to think about. It's something that you need to be aware of. So it's an issue. Usually when people talk about cryptography, the kind of thing that everything is the same, and it's not the same. When we're talking about hashes, for example, one of the common things that I hear is that I've encrypted with SHA-1. Or I encrypted with SHA-512. Well, not. You did not encrypt the SHA. A hash function has only one job. Taking lots and lots of information, boiling it down and getting a very short piece of information. But that's also true for checksums. So if you write CRC32 or something similar to checksum, you get the same concept. You process a lot of information against some validating code at the end. However, CRC32 and SHA and other constructs are not the same because cryptographic hashes, which is a specific type of hashes, try to give you a guarantee. They try to give you that if you change one bit in the input, you will get a dramatically different output. More than 50% of it should be different. And if it's not the case, this is a very bad function to use. Because that means that an attacker can now use that to find collisions. Collisions meaning find a different message that will give him the same output. So short story, MD5, for those of you who are familiar with it, used to be a very common hashing algorithm way back when. And a couple of years ago in Black Hat, if I remember correctly, I don't remember her name, but a researcher from China, if I remember correctly, showed a way to find collisions in MD5. And what happened? Immediately, you can actually generate whatever you want to get the same kind of MD5 hash on it. Which means that now it's open for attackers to use MD5 to modify inputs or select their own inputs. And you will still think it's the same thing. It's paramount or analogous into some developer writing the library and giving you an affirmation, this is my library, I wrote it. Here's my MD5 signature. And then someone else uses MD5 which will give you some malicious piece of code and you will not be able to tell the difference. So just as an example, what does it look like in real life? So if we take a function SHA1 in this example, at the quick run for blah, blah, blah, we'll give an output 2FD, blah, blah ending in B12. Let's change one character where I change the D to a C. And you can see that the output is dramatically different. So that's the purpose of a cryptographic hash function. So if you've changed just one thing, it will be dramatically different. It'll be very difficult to find two different sources that get the same output. Why is this important? It used to be very, very difficult to attack SHA1, two to the power of 80. That means that's a lot of compute. However, with recent advances last year, or sorry, this year, early this year, this was reduced to two to the power of 68. Well, that sounds pretty tough yet, right? So if you go and spend like 100K in Amazon, you can crack SHA1. And that means that if you're using Git and you're counting on Git to make sure that the commits have the right hashes and don't have like two people committing the same thing or malicious person committing something and you get the same kind of commit. Well, that's not true anymore for an SHA1 attacker with lots of money. But it might be even true in the future if there are other advances. So I'm not really worried about Git because that's like not a really viable attack surface. But Git had discussions to move away from SHA1 to SHA256 or SHA512. And that's probably the most common recommendation right now. Don't use SHA1 anymore. Symmetric function, something you're probably more familiar with, which is cryptographic function that given a key, you can use it on a piece of information and then it will be hidden. Use the same key again, you get the information right back. So example, take AS. AS is the currently known best practice to use for encrypting symmetric information. So I just like, it's set a code but like Python notation, padded it with 21 zeros, get something, change a bit, get something dramatically different. Why is this important? It's important because if the cryptographic function produces an output that has some sort of information in it, it doesn't look like random noise. It means that I can go ahead and break this algorithm. I'll give you an example. One of my friends, he's a master thesis, was to break an algorithm called Web. Might have heard of it for Wi-Fi. And the reason it was broken was because that when you used the algorithmic function called RC4, RC4 wasn't stable. The first 1,000 or 2,000 bits coming out of RC4 had a bias. So you can guess with good certainty what was the key that produced that output if you recorded that output. So once you did that, just record some information out of the air and now you know the key for that web encryption. But that's pretty bad. You want something to be very stable, very good. So AES is currently the standard and it's a good standard and you could be very happy using it. And there are other cryptographic algorithms out there to supplement it when the time comes. As symmetric cryptography, I'm not going to go into a lot of length here but that's what you probably all know from private public keys. Basically what they mean is that if you have a pair of public and private keys, you can give everybody your public key. They can encrypt the message with the public key that you gave away but because you're the only one who has a private key, you're the only one who is able to decrypt that message. So hand-wavingly, this is the way this works. And this is something that a lot of our internet, data communication is based on. There was a presentation, I don't know if you've seen the Twitter stone about it. I think it was, I'm not sure if it was yesterday or two days ago in Black Hat by a company called Time AI. They do 5D encryption with quasi-prime numbers and lots of other. They enhance their cryptographic functions with music and emotions and it was like, I could not believe that this was a Black Hat talk. So choosing like vetted, known, good algorithms is what you should do. You should not invent your own algorithms and I'll come back to that message in a moment with some examples. So what is a signature? A signature is having some private key and using that in order to provide a proof to everyone that a piece of code or a piece of message is something that you actually guarantee came from you. So how does that work? So I'll take my message, could be my library or something similar and I'll calculate or compute the hash of that message using the sha1 or something similar from before. Then I'll provide a signature. A signature is just taking a public private key algorithm. Using my private key, I'll encrypt the hash. Now I have an encrypted hash that was encrypted with my private key. So I'm not giving anyone my private key but I know that I can assure someone that it's mine. How can I ensure someone that it's mine? I give everybody my public key and I give them the message. They will compute their own version of the hash because they do it by themselves and don't trust me anymore. And they decrypt the message using the public key. Now if they got the same key, the same hash, that means that I am the owner of the private key, of the public key, of the private key and therefore this message came from me. Sorry. So the whole concept of signature is based on the idea that I can share something publicly, I can keep something private, not tell that to anyone but using that information I can also convince you of my identity as a holder of that private key. One of the things and probably the last tenets for this very short introduction is the idea of randomness. Almost everything that we do in cryptography is somehow centered about randomness. So if we don't have a very strong randomness source, everything breaks and I'll give some examples of that. So usually when we talk about randomness, we talk about two different things. The first one is called the TRNG or a true random number generator and the other is called PRNG, absurd random number generator. The big difference between the two is that the PRNG is a function. If I'll give it a known starting point, it will always get to the same result. Change the starting point, you'll get a different result but it's derived in deterministic fashion. TRNG, I have no idea what's not gonna happen. So it's just like measuring neutrons from the air or like measuring electromagnetic interference. It might be zero, it might be one, I have no idea how it's gonna happen. So a good TRNG will give me bits with a probability of 50%. I don't know what it would be. If it was something like let's say 49%, I would be able to break that random number generator. So we need something that's very, very stable. So how do you use that? You take a PRNG and you provide it with an input that's come from a real world entropy source, something that's actually truly random. So what happens when it isn't random? Sometimes people misuse random numbers. For example, when they're writing code and they need to use nonces. Everybody are familiar with what's a nonce? Okay, so a nonce should be just a random number. It shouldn't be constant, it shouldn't be hard coded into your code until it is. And when it is, funny things happen. So I'll give you an example. Probably heard of Bitcoin once or twice maybe. So Bitcoins is actually a cryptographic operation. So what are coins? Coins are actually going and trying to find inputs that given a hash function will provide a pre-known output. So that's the difficult problem. Not because it's mathematically hard, but because it's very difficult to find those inputs. So what do you do? You try a lot of different attempts. Found one, you earn the coin. Now you are an owner of a single Bitcoin. This is exponentially harder as time goes by, which means you have to invest more time, more resources, more CPU power in order to actually mine those Bitcoins. But the basic principle still holds. Wallets or your Bitcoin wallets are just identities. They are something that represent your private and public keys. And transactions are actually just saying, I'll take this piece of money and I'll give it to that private key or that holder of that private key. And this is a transaction. Just shifting money or shifting coins or pieces of coins from one source to another. I should have clicked like 20 minutes ago. An important thing to note, if you lose your private key, you lost your money because your coins are held by your private key. If you don't have access to your private key anymore, you don't have access to your coins. Something to keep in mind when you're playing around with Bitcoin. So the last thing I want to talk about is called elliptic curve cryptography. If you're familiar with RSA, basically the same thing, much cheaper to execute, much less compute power, same guarantees for security. Bitcoin is using these elliptic curve cryptography operations in order to move money about. So that's the basic algorithms behind Bitcoin. So this is a screenshots from a Bitcoin transfer. So what you can actually see is that this value here, this is the address of the source, which is actually the hash of my public key. And I am moving money, 7.179 blah blah bitcoins, into two different addresses, and the addresses are just the hashes of the public keys of the recipients. This is everything that there's to it. This is the entire Bitcoin idea in a slide. So how would you go about attacking this? So I will not go into bore you with the mathematical details behind this, but I'll try to direct your attention to a couple of things. The transaction actually happens when I, as an owner of a Bitcoin, will sign over a portion of that coin into a new address, to a new private key, or sorry, to a new hash of a public key. In order to do that, I have to work with a couple of components. The hash of the message, K, which is random, R, which is the multiplication operation under elliptic curves, and the signature. And the way to calculate the signature is outlined in the formula in the bottom. So there's something here, which should stick out like a sore thumb to everyone who looks at it, which is, maybe I can show my hair. K should be random. And sometimes when implementers are reading the spec, I say, okay, K should be random, so I'll select a random number. So what happens when K isn't random? Assume that K isn't random. If I can go over on the block, look at all the blockchain, all the Bitcoin transactions, and find two different transactions that share the same random number. Suddenly, this is a problem in like sixth grade algebra, because if I know the value for K, I can just move about the equation, isolate K, and solve for everything else, and I solve and I solve, and finally I have D. Now I have the private key, because in elliptic curve operations, when you're not using random numbers, everything breaks. So it's like, it's a tenant of using elliptic curves. So you say, okay, this is like nonsense. Who wouldn't use random numbers in the real world? This like never happens. And the answer is, well, of course it does. So this is a screenshot of like many, many years ago, 2013, when somebody noticed that people are stealing money from wallets. And how did this attack happen? Because somebody else was probably a bit brighter, noticed that people are using bad wallets, or bad wallet software, where the developers for that piece of software, for that wallet, didn't realize that they need to generate a new K for every transactions. So what they've done is just searched the transaction logs for two different transactions using the same random number, extracted the private key, and stole all of their Bitcoins. This was in the entire attack. So, you know, that's kind of, if somebody wants to mess with Bitcoins, like they had it coming, I have no problems with that. But you say, this shouldn't happen in like real world applications, like big sized, interesting stuff. So how does that look like in the real world? When you generate a random number, what you should probably be doing is something like open slash dev slash random, and pull some number of bits out of it, maybe 30, I don't know, just throwing a number there. But you should do this for every time that you need a random number, because when you don't, you get something like this. You choose the random number very securely, once, and hard-code it, which is like analogous to saying like, what's my random number? Four. It was chosen by a fair dice roll. I'll skip this. Okay, we'll come back to the point of the randomness in a moment. I want to show you a piece of code and ask everyone, can everybody see the problem with this piece of code? Any hands? It was pretty famous for a while. Okay, we have one person. Two persons, excellent. So I'll highlight it for everyone. So this piece of code is actually the verification code for X509 certificates on iOS, or it used to be. And what this means is that when you're doing a TLS transaction or Instacell transaction, somebody needs to check the certificate. How do you check the certificate? Just the same way that we talked previously. Just check the public keys, find out the hashes, compare them, check them. And the way that the code is written is that if there's an error, some check didn't pass, go to fail. But what happens here is you have a double line. So the first line is in the scope of that if. The second line isn't in the scope of anything. So anything written after that never executes. Whatever you go into that point, you immediately go to fail. So how is that interesting for an attacker? If you specially craft your certificate that you would pass each and every check up to that point, even though your certificate is invalid, you will still pass the test. Because nobody tests for everything, you just test up to that point. And that meant that attackers could create certificates for, I don't know, for example, iOS apps that are invalid and malicious, but have certificates which are bad, but pass the verification process. So special attention needs to be given to these kinds of cases. Am I missing a slide, let me check. Yeah, I should have said something here and I skipped it, so let me circle back for a moment. Okay, so I said that this shouldn't happen in the real world. Sony, you might have heard of them, have a device or had a device called the PlayStation 3. And the PlayStation 3 was pretty awesome, everybody liked playing with it, but they couldn't really copy the games. Why? Because there was a DRM, Digital Rights Management Protection on the games. But what Sony didn't really take into account or their developers didn't think about very thoroughly is that when they signed the games, they signed them with elliptic curves, but they chose a single random value and it was hard coded. So when the guys at Overflow found this out, they understood, okay, I can just take two different games, compare the signatures, find the random values that they used, derive the private key, and now I can sign whatever game that I want for Sony because I have the private keys because they didn't use random values. So this was a very big thing for a while because those hard coded numbers were hard coded into the PlayStation 3 hardware device itself, the firmware, and they couldn't really update this. They couldn't circumvent this, but they just lost a lot of money because someone made a mistake about assuming something about random numbers. Sorry, I completely missed my point here. Circling back to Bitcoin, everybody remember this screen for two and a half years ago, something like that? So attackers behind WannaCry built like, I don't know, let's call it a GUI or something that will give you some information. How can you get the keys in order to get back all your files that they encrypted? Just send me some money to this Bitcoin address. And they were supposed to send you back the keys and everybody would be very happy. So a couple of things happened. The first one was that obviously they never sent the keys. The second one was that the WannaCry attack was stopped pretty much in the middle because of a different operation. They had like a failsafe, so they could stop the propagation of the malware from going everywhere because that's like a different story, but the malware would check if a specific domain name was registered. If it was registered, it would stop to work, okay? So while that domain name was not registered, it would continue to propagate. So one of the security researcher would just finished if you were following up on the news, just finished his trial, find that that out from reverse engineering the software, he registered that domain, he paid like, I don't know, $5 for it and stopped WannaCry. So that was the first thing that was really not very smart about WannaCry. The second thing was that they kind of missed the point of using Bitcoin. Bitcoin is a confidential service, but it's not an anonymous service. It means that everybody can be the owner of Bitcoins and their identity is protected, that you don't have to tell anyone your identity, but everything you do is always logged, is always recorded. It's part of the very mechanism of how transactions on the blockchains work. And that means that if I'm a malicious attacker and I'm asking people to send money over to my wallet, everything is traceable, everything is accountable, and it's part of the design of the system. And if I want to cash out, now I have a problem because if I try to cash out, somebody can just say, okay, now you linked that identity with this real world credit card. So they had money stuck there, they had about $70,000, if I remember correctly. They had it stuck there for a couple of months, I didn't even thought about the solution, which was just doing cash exchanges in Macau, something like that, to go over there, pull out the money very fast and disappear. But while they were doing this, they really couldn't touch the funds, because whatever you do with the funds, it's always traceable. Okay, so how does this look in the real world? New example, who uses BitLocker, or at least heard of it enough to understand the term? I don't believe you. Who has Windows laptops? Really, everybody runs Linux? Wow, cool. I'm really proud of you guys. So BitLocker is, I wouldn't call it a protocol, but it's like a feature where your hard drive will self-encrypt everything, so if somebody steals the hard drive and connects it to a new computer, he can't read the data that's on that device. That's a description of that feature. What really happens is that when you connect it to the software, to the operating system, the operating says something like this. Are you a hard drive or SSD or whatever that supports hardware encryption and BitLocker supported devices? Yes, of course I know encryption. Let's use my encryption. So if you have a hardware-supported encryption on your hard drive, it will use the hardware version. If you don't have support, then Windows will simulate that support in software. What's the problem with that? The problem with that is the very premise that hardware is actually better than software, because the way that the hardware developers did that was mumble about what they did. They had a password that's used by your BIOS in order to encrypt or decrypt information from your hard drive, and they had a key, but there was no relationship between the password and the key. So you can type any password that you want, the key would still be fixed. It would be orthogonal to the password that you used. So they didn't tie together in any way. Second thing is they used the same key to encrypt the entire drive, all of the different partition, all of the different blocks and sections, which means that I have lots and lots of different blocks of encrypted data that I can compare against that are all using the same key, which means that if you had a bad implementation, you just made my life easier as an attacker. And the last thing is they didn't really use random keys. I'm just dissing here, but think of it as an equivalent of a 12 character password where it's all once, okay? So they didn't randomize the password. So you had the same password for all blocks on your hard drive, which didn't have any correspondence with a password for your BIOS or anything else. So you couldn't customize it, it didn't tie into anything from the real world. And that meant that, I'll skip that, and that meant that all of those drives were very, very weak from a cryptographic perspective. It's almost trivial to break them. However, the operating system by default will choose the hardware encryption over the software encryption. And that meant that any laptop that you probably have or had for the past year or older than that didn't really have the security guarantees that you thought it had by using the BitLocker and similar properties, similar features. Here's just, I don't know, I just found it like extremely funny example. Somebody on Stack Exchange asked for an algorithm to encrypt your password. I know you can't read it, so enlarge it. So the method that he was suggesting to do was to take a Base64 encoding of your password and then reverse it, apply Base64, and now you have an encryption. So amount of things that are wrong with that sense and so on. He summarized this much better than me. The first thing is that Base64 is a bad choice because it enlarges the space requirement to store the same kind of information. The second thing is obviously, this has nothing to do with cryptography, it's just encoding the same information in a different way. Reversing the encoding does nothing for security, just means that I have to reverse it again. And the basic thing is that this was an entire thread on Stack Exchange. Should I use MD5 to encrypt my files, and encrypt my passwords, where one, MD5 is not an encryption algorithm, and two, it has nothing to do with it, it's broken, use something else. And this guy came along and suggested to use this amazing piece of code that he wrote in order to protect everybody's password. So be careful of where you get your advice. I'm not dissing Stack Exchange, I'm just saying you should vet information that you receive. I think it's my last example. I do want to explain the concept and what I find problematic with it, but the basic idea is that it is actually a good piece of software, it just had its own limitation. So what this guy, he wrote a piece of software called Crypt Hook, and the problem he was trying to solve is that you have information on server A, and you want to communicate with server B, but you don't have the facilities to encrypt the information, you can't change the software that's running on the servers. So what he said, okay, I'll hook the system calls, and every network packet that transfers from server A to server B, I will encrypt it myself. So I will create an out of band encrypted channel between the two servers that has nothing to do with the software running on them. It will still transparently use the network stack, and I will encrypt the network stack. Out of the box, it's not like a bad idea, this really solves a real problem where you can't touch the software. On the other hand, the choices that he's made made it very, very weak. So he chose to use a GCM, which nobody should really care what it means, to do authentication, but he encrypted everything with a fixed key. So every packet was encrypted with the same key. Not only was that every packet was encrypted with the same key, there was no difference between the packets, so everything was encrypted exactly the same way. So it was absolutely easy for an attacker to capture a packet and replay it, send it again over the network. So if you had a packet that says, they transfer $1000 to my account, you can just capture that packet and replay it again and again and again, because no one would know, because there's no such information inside the packet to stop that. Also, you can change the order of the messages. You can do whatever you want with it, like dropping some of the messages because his encryption scheme didn't think about those kinds of edge cases or use cases. But also, it meant that if I broke the key once, because it was fixed, it was hard coded, that meant that I now had the key to every communication that would ever happen with this piece of software, which is tentative to just reading the source code because the key was there. So the question is, is everything on fire? Is everything bad? So obviously the answer to that is no, it's not everything's on fire, not everything is bad. But you should really pay special consideration whenever you're touching something related to crypto. Crypto is hard. There are experts, usually PhDs, that spend years and years of their lives researching crypto problems and crypto properties in order to make sure that whatever they're doing is very, very safe. You're not going to outperform them, you're not going to outsmart them, and you probably shouldn't be trying. Never roll your own crypto. Use best practices, use what's already out there. My next slide, I'll give some recommendation. But also, you have a special use case, you have some problem that's unique and you don't know if the current tooling is able to solve that. Well, ask around. Ask an expert. I can recommend two, let's say expert advice channels that you can use. The first one is using Reddit, the crypto subreddit, but also the crypto stack exchange. Both are wonderful resources to consult with real world experts that can help you understand your problem and the right kind of tooling, the right kind of algorithms that you can use to solve that unique problem. More than that, you can always pay consultants. I'm a consultant, I'm getting paid to give advice, that's fine. There are experts that you can talk to on Twitter, anywhere else, you will get advice. People are nice, basically, most of the time. You can also pay a crypto review firm to go and look over your crypto code to make sure you haven't done something horrible like what happened to Sony. You don't want to be in that position where you wrote your own crypto or your team wrote some crypto because you thought you would be really solving something and you just horribly broke the entire security premise of your product. So what's my advice to you? That's probably the slide you should copy or photograph or just listen very carefully. The first one is that make sure that you're using the right libraries for you. Personally, I never recommend OpenSSL. Who has experienced using OpenSSL APIs or implementing OpenSSL code in their own ID or in our own product? Anyone using OpenSSL? How sorry are you? Have you tried anything else? Not really. Not really. So at least my opinion of OpenSSL, it's a big, large, bloated piece of software that tries to do everything and most of the time doesn't do them the most efficient or the most proper way and it gives you, I used to have a boss that told me that C is a wonderful language. It gives you every tool possible to slit your own throat. So in a sense OpenSSL is the same way. They support everything, every legacy algorithm, every parameter ever conceived for anything and if you will misuse this or configure it wrongly or use the wrong parameters, you won't even know that you broke your crypto. So my first recommendation for you is just use something simpler and you know the world has advanced. There are lots of very good libraries out there. I can recommend BoringSSL. The Golang crypto stack is excellent. NACL is also very, very good. NSS is very good. I do want to say that all of the libraries I mentioned here are good and I recommend them myself. Sometimes they have issues, they have bugs, they have patches that you need and this is actually a good thing because that means that somebody is maintaining this, somebody is actually looking if there are any issues and somebody is trying to fix them. So whenever such a thing exists, take that into your consideration, into your dependency stack and make sure that your own code is up to date. Never trust people that roll their own crypto. There are lots of like, oh yeah, we have a student, he's really brilliant. We ask him to write our crypto stack. That's not a good idea, even if he is brilliant. Use best practices, use what's already out there. Just use it correctly. You have a much easier time, much better time overall. The last thing is that, sorry. The last thing that I wanted to mention about that is that not every feature that exists in crypto is actually something that you need. So cryptography has a lot of building blocks that are used in many, many different ways. Some of them are very esoteric. Some of them are like the mainline use cases. 90% of the time, you need the mainline use case. It's already described, it's already known. Just use that. Don't invent anything. Don't try to like, oh, that's a nice looking piece of technology, just like, let's use that instead. You need to think about it and you probably need some cryptographer to let you know if you did this correctly or not. So what you can do, update your libraries. I've seen so many customers, so many people who use the OpenSSL and like in version 1.01 or something like that and it's not updated at all because it's hard to update and they're afraid it will break something and with OpenSSL that's very cumbersome anyway. So make your life easier. Make sure that you have thought of how are you going to update this? How are you going to fix this when the time comes? If you want to become an expert, my recommendation to you is to start small. Go to trainings, to workshops, hear talks, go over YouTube, read a book. You can become an expert on cryptography without knowing math, you don't need a math degree in order to better understand crypto. You probably need a math degree or even a math PhD to invent crypto, but not to use it, to use it properly. Study, like everything else that we do. Study, this is a domain of knowledge that you can use, you can learn. It's not scary, it's not something that you should be afraid of. Down the line, you probably want to either outsource or hire the right people to look at cryptography very closely, but if you're not inventing cryptography, just use something that someone else already did. It'll make your life easier and probably get better security out of it. With that, I would thank you very much. I'll be happy to take questions now in a moment, and if not, I'll be also outside later to take more questions. Yes, sir. That depends on what your desktop is, if you're on Linux or in your own Windows or you're on Chrome OS or differently, but I would trust with a mild degree of assault attached to it, but I would trust the operating system to hold secrets. They're usually pretty good, depending on how much trust you need for that secret. If I have a desktop application, usually that means I have my own laptop or my own story, my own bank accounts or something like that, that's secure enough. If I have a production server hosting secrets for my 100,000 customers, that's a different question. There I would use an HSM or something similar. HSM is a hardware security module. That's actually a piece of hardware that holds secrets and lets you do cryptographic operations without revealing those secrets. So we can talk about that later. Yeah, yes. Yeah. I fully agree. I'll repeat that. The Capital One issue hand-wavingly, was not actually an encryption issue, was a permission issue. So if you give someone permissions or you commit to GitHub your keys, then you actually gave everybody permission to use your keys to do whatever they want to do. So the cryptography is still very strong, but you haven't protected your keys. So in a sense that's what happened with Capital One, both for roles and permissions for the access list they used for attacking. Well, here's where you actually need an expert to come and help you and look at your own specific use case. But if you encrypted your entire database, but you kept the key in a script by that database, then you haven't really done anything. But if you encrypted your entire database and the key comes from a different component, which is checks your permissions and stuff like that, then you already have a different security model. So this is actually a more complex question to answer and not necessarily relevant for client-side encryption, depending on what you're trying to solve. Okay, more questions, please. Be brave. No one? Go in once. Thank you very much.