We're sorry but this page doesn't work properly without JavaScript enabled. Please enable it to continue.
Feedback

Being Boring: A Survival Guide to Ruby Cryptography

00:00

Formale Metadaten

Titel
Being Boring: A Survival Guide to Ruby Cryptography
Serientitel
Anzahl der Teile
50
Autor
Lizenz
CC-Namensnennung - Weitergabe unter gleichen Bedingungen 3.0 Unported:
Sie dürfen das Werk bzw. den Inhalt zu jedem legalen und nicht-kommerziellen Zweck nutzen, verändern und in unveränderter oder veränderter Form vervielfältigen, verbreiten und öffentlich zugänglich machen, sofern Sie den Namen des Autors/Rechteinhabers in der von ihm festgelegten Weise nennen und das Werk bzw. diesen Inhalt auch in veränderter Form nur unter den Bedingungen dieser Lizenz weitergeben.
Identifikatoren
Herausgeber
Erscheinungsjahr
Sprache
Produzent
ProduktionsortMiami Beach, Florida

Inhaltliche Metadaten

Fachgebiet
Genre
Abstract
We all know that security is hard, and that math is hard, but what happens when you put them together? Cryptography is an increasingly essential tool for building secure systems, but also a perilous minefield where any number of mistakes can lead to insecure systems. This talk will take you step-by-step through the difficulties of building secure cryptosystems on top of Ruby's existing OpenSSL bindings and contrast that with RbNaCl, a next generation Ruby cryptography library specifically designed to be more mistake-proof and put cryptography "on Rails". Attendees will hopefully learn that the best approaches to cryptography rest in making systems simple, straightforward, and boring... in a good way.
Elektronischer ProgrammführerEreignisdatenanalyseKryptologieProgrammierungMultiplikationsoperatorGanze FunktionComputersicherheitTwitter <Softwareplattform>Vorzeichen <Mathematik>MathematikDivergente ReiheQuick-SortQuadratzahl
ComputersicherheitQuadratzahlTwitter <Softwareplattform>
ChiffrierungKryptologieSpieltheorieOffene MengeMultiplikationsoperatorMailing-ListeProgrammbibliothek
ProgrammbibliothekSpieltheorieComputeranimation
Message-PassingTypentheorieChiffrierungQuaderSchlüsselverwaltungProgrammfehlerMAPProgrammierungComputersicherheitFormale SpracheMathematikComputeranimation
MathematikCodierung <Programmierung>Symmetrische Matrixp-BlockAdvanced Encryption StandardZufallszahlenMathematikComputersicherheitProgrammierspracheLie-GruppeChiffrierungLesezeichen <Internet>Quick-SortKryptologiep-BlockGüte der AnpassungVersionsverwaltungMultiplikationsoperatorBitPrivate-key-KryptosystemSymmetrische MatrixLesen <Datenverarbeitung>RandomisierungRechter WinkelEinflussgrößeBitrateMetrisches SystemProzess <Informatik>Figurierte ZahlRoutingBeobachtungsstudieBenutzerfreundlichkeitWeb SiteBus <Informatik>
Chiffrierungp-BlockZufallszahlenBlockchiffreAdvanced Encryption StandardImplementierungIkosaederFigurierte ZahlVersionsverwaltungAuflösung <Mathematik>ATMChiffrierungComputersicherheitComputeranimation
ZufallszahlenInformationSchlüsselverwaltungp-BlockLeckKryptologieATMComputeranimationDiagramm
p-BlockATMGamecontrollerQuick-SortNichtlinearer OperatorDifferenteChiffrierungComputeranimation
ZufallszahlenAdvanced Encryption StandardATMp-BlockQuick-SortGraphiktablettZufallsgeneratorMultiplikationsoperatorStreaming <Kommunikationstechnik>PseudozufallszahlenChiffrierungStromchiffreMereologieBitDisjunktion <Logik>RandomisierungSchlüsselverwaltungMehrrechnersystemBildgebendes VerfahrenComputeranimation
PseudozufallszahlenBildgebendes VerfahrenGraphiktablettEgo-ShooterChiffrierungMathematikDiagrammComputeranimation
Quick-SortATMSchlüsselverwaltungMultiplikationsoperatorGüte der AnpassungInformationLeckMessage-PassingTransponderComputeranimation
ChiffreMathematikChiffrierungDisjunktion <Logik>MereologieQuick-SortAutomatische HandlungsplanungAuthentifikationMessage-Passing
ZufallszahlenAuthentifikationMessage-PassingChiffrierungSchlüsselverwaltungVerschlingungDickeComputeranimation
InternetworkingChiffrierungOrdnung <Mathematik>Quick-SortDigitale PhotographieFlächeninhaltComputeranimation
Quick-SortChiffrierungProtokoll <Datenverarbeitungssystem>IPSecNeuroinformatikAutomatische HandlungsplanungCybersexBitrate
IPSecQuick-SortStandardabweichungRechter WinkelIPSecComputeranimation
TLSAutomatische HandlungsplanungBitGraphiktablettOrakel <Informatik>Informationp-Block
MenütechnikSynchronisierungProtokoll <Datenverarbeitungssystem>BinärdatenRechenwerkChiffrierungAuthentifikationAbstraktionsebeneNormierter RaumPersönliche IdentifikationsnummerTorusWeb SiteProtokoll <Datenverarbeitungssystem>Message-PassingAuthentifikationBildgebendes VerfahrenKryptologieNummernsystemDivergente ReiheChiffrierung
ChiffrierungIPSecsinc-FunktionOffene MengeMessage-PassingLokales Minimum
Wurm <Informatik>Inklusion <Mathematik>Message-PassingSprachsyntheseDienst <Informatik>ChiffrierungPatch <Software>PaarvergleichMultiplikationsoperatorKonstanteQuick-Sort
Wechselseitige InformationRechenwerkMinimumMultiplikationsoperatorInformationResultanteMatchingPatch <Software>System FDisjunktion <Logik>PaarvergleichQuick-SortLokales NetzKonstantePrinzip der gleichmäßigen BeschränktheitBitrate
Public-Key-KryptosystemAggregatzustandQuick-SortKonstruktor <Informatik>
CodeKryptologieProgrammbibliothekCodeChiffrierungQuick-SortMultiplikationsoperatorVersionsverwaltungSoftwaretestKryptologie
Schreiben <Datenverarbeitung>ProgrammbibliothekKryptologieMultiplikationsoperatorProgrammbibliothekKryptologieRechter WinkelSchnelltasteChiffrierung
ProgrammbibliothekSelbst organisierendes SystemKryptologieVierGoogolBitQuick-SortClientProjektive EbeneAlgorithmusDämon <Informatik>Deskriptive Statistik
Physikalischer EffektDeskriptive StatistikDistributionenraumKonfiguration <Informatik>BinärcodeProgrammbibliothekQuellcodePhysikalisches SystemStandardabweichungNatürliche ZahlBernštejn-Polynom
Public-Key-KryptosystemKryptologieQuick-SortElliptische KurveElektronische UnterschriftWikiSymmetrische MatrixChiffrierungKurvenanpassungDienst <Informatik>Private-key-KryptosystemMultiplikationsoperator
Private-key-KryptosystemQuaderMereologieMessage-PassingViewerSchlüsselverwaltungEinfache GenauigkeitChiffrierungWeg <Topologie>ZufallsgeneratorAggregatzustandMinimumPhysikalisches SystemMultiplikationsoperatorAusnahmebehandlungDemoszene <Programmierung>BildschirmfensterRandomisierungSichtenkonzeptNetzbetriebssystemAuthentifikationComputeranimation
KryptologieGewicht <Ausgleichsrechnung>Quick-SortKryptologieStreaming <Kommunikationstechnik>ChiffrierungInklusion <Mathematik>Stromchiffre
DualitätstheorieNational Institute of Standards and TechnologyHintertür <Informatik>ZufallsgeneratorElliptische KurveChiffrierungKryptologieHochdruckQuick-SortQuader
GravitationsgesetzRechenwerkElektronisches ForumInklusion <Mathematik>Quick-SortPublic-Key-KryptosystemQuaderKryptologieWeb SiteMessage-PassingKurvenanpassungUmwandlungsenthalpieUnternehmensarchitekturPrimitive <Informatik>NeunzehnMultiplikationsoperatorDatensatzFunktionalVererbungshierarchieGanze FunktionSchnittmengeDifferenteMathematische LogikAuthentifikationAlgorithmusDienst <Informatik>Automatische HandlungsplanungElliptische KurveChiffrierungSchlüsselverwaltungPolygonEllipseAdditionAusnahmebehandlungComputeranimation
ProgrammbibliothekMultiplikationNichtlinearer OperatorZentrische StreckungSpiegelung <Mathematik>QuaderPublic-Key-KryptosystemPrivate-key-KryptosystemSkalarfeldComputeranimation
VerschlingungSoftwareVideokonferenzEreignishorizontFehlermeldungComputeranimation
Transkript: Englisch(automatisch erzeugt)
We're ready to go here. So it used to
be you didn't have to think about security when you're writing a Ruby program. Well, guess what, pal. Times have changed. There's all sorts of bad people out there, and you gotta know how to stop them. I'm not gonna do the entire talk as any Crockett impression, sorry. So I am Tony
R. Siri, or Bascule on Twitter. I work on the, or work at the infirma- I work at Square on the information security team. And my talk today is about cryptography, and, you know, just want to encrypt something. How hard could it possibly be?
The answer to this is definitely hard. So how hard is it? Well, today you're gonna drink from the fire hose, and I'm gonna show you exactly how hard it is. So a quick editorial here. We're gonna talk about attacks. We're going to talk about how to defeat them using something called authenticated encryption.
And then we're going to learn how to completely avoid all these problems by just letting cryptographers do all this stuff for us. So I think Ruby's traditionally been in a pretty bad situation when it comes to cryptography. And the main reason for this is the OpenSSL library
has been the only game in town for quite some time. So I think we can change this. I think this is a fixable problem. But to do that, we really need to know how the hell does crypto actually work. To answer this is magic. But not really
magic. It's actually just math. So there's two types of encryption ciphers I'm gonna talk about today. We'll show how one builds on the other. The first is called symmetric, so here we have Alice, who just wants to send a message to herself. Or rather, just put this message away in
a box and lock it, and then she can use the key to open it again and get the original message out. The other is asymmetric, so Alice wants to send a message to Bob. Same idea here. She's gonna put it in a box and lock it with one key, and then Bob magically has another key that lets him get the
message out. So the big problem with encryption is it lies at the intersection of math and security. So like, math is hard and security is hard, and when we put all these things together, especially when we're talking about doing this in a programming language where we have bugs, things are
gonna get pretty hard. And this is one of my favorite quotes from Cryptonomicon. So this is kind of the situation we're in, I think, in the Ruby world, that most of the encryption gems out there are designed by cryptographers. They're designed by sort of amateurish
people who are trying to, trying to put everything together, but maybe just don't quite know how. So I'm gonna go through all the attacks on symmetric crypto. Unfortunately I don't think I have time to do your asymmetric crypto, so left a bunch of those attacks out, but guess what,
it's even worse. So we're gonna talk about AES today. AES is a symmetric encryption cipher. It's great. I would recommend you use AES, but sort of like aim away from face, read all instructions before proceeding, kind of thing. This is how AES works. It's a block cipher,
so it works on fixed size blocks. So we're gonna take a sixteen byte piece of plain text and we're gonna use a key, which can either be sixteen, twenty-four, or thirty-two bytes. You want to generate that randomly. And from that we're going to get a sixteen byte block of ciphertext.
So that's all well and good. AES works great. There's just this little problem. How do we encrypt something that is larger than sixteen bytes? Well, one solution to this, PHP decided to use a different ver- so AES is derived from a cipher called Rhindol. PHP shipped the version of Rhindol with a
256 bit block size. So this is awesome. It's a completely non-standard version of AES that only PHP uses. So let's not do that. So let's figure out how to do this, right. So the naive solution to this is to use
something called ECB mode. So there's this guy here. He apparently couldn't find out how to do encryption with OpenSSL itself. So he went off and made his own gem to encrypt stuff with ECB mode. You see there, yeah, see security
nodes, ECB mode only. Problem with ECB mode is it's really, really bad. So the ECB mode would have you do is just take all these blocks of plain text and encrypt them under the same key. So what's
the problem with that? Well, it leaks information. So let's say this is our plain text. We want to encrypt. If we run that through ECB mode, we get something that looks like this. So I think you can all see from this that this thing isn't very well encrypted. We can totally, can totally see what it is.
So what's the solution to this? So we need to use a different block cipher mode of operation. There's lots of these guys. We just kind of have to pick one. There's all sorts of various trade-offs. The one that people have mostly settled on
today is counter mode. So counter mode is fairly easy to understand, I think. It's sort of similar to a one-time pad. So what we're gonna do is take a block cipher like AES and try to turn it into a stream cipher. So what we're gonna do is effectively generate a bunch
of pseudo-random numbers. So we feed in a nonce, which is some secret starting place, and a key, which is the same as what we were putting in before. And then there's this little counter, and every time we encrypt a block, it's just gonna count by one. So what we're actually gonna do is combine the nonce and the counter and encrypt that
with AES, and what we're gonna get is a little bit of pseudo-random pad for each part of the plaintext. And for each of these pads, for each of these blocks, we're gonna XOR the pad with the plaintext, and that's gonna give us our ciphertext. So if we go back to our little Ruby gem image here, what we're gonna do is
combine this with a pseudo-random pad, and what we're gonna get is the ciphertext. So I hope you can see that little subtle change there. So this is actually encrypted right now. We can no longer see that gem. And now we're
done. Success. We, we've, we've attained confidentiality. Except the problem, repeating nonces will leak information. So we can't ever use the same nonce and key. So the solution is just don't do that. So we've got another problem here. Support for counter
mode in Ruby OpenSSL is spotty. So unfortunately we can't use sort of the industry best practices here. And what we're gonna use is CVC mode. CVC mode is fine. There are a few small issues with it. But unfortunately I don't have time to go into them. So next problem. Attacker, who we hand this message
to, can manipulate it. This is something called malleability. So let's say our plaintext is attack at dawn and we encrypt that and we have a ciphertext and we hand that to an attacker. Let's say this attacker is able to guess what the plaintext was. So what this attacker can then
do is XOR part of the ciphertext with what he thinks the original plaintext is, and then XOR that again with what he wants it to be. So what we get is this sort of like manipulated ciphertext. And now when we decrypt it, it gives us the wrong thing.
This isn't what we expected it to be. The solution to this is to use something called a message authentication code. When we combine this with a encryption cipher, what we get is something called authenticated encryption. So with a MAC, what we do is we take the message and then we have
a key, and when we combine the message and the key, we get this fixed length tag. So we know we have the right message when we take the same message and the same key and then we get the MAC we expect. So once again, there's a whole lot of these. Like HVAC is the one I'm sure you've
heard of if you've heard of one of these. The others are somewhat less common. So now we have yet another problem. What order do we combine the encryption and the MAC? So there's effectively three ways to do this, and
common internet tools have all sort of chosen their own different way. So the first is called MAC then encrypts. This is, was used by SSL and TLS. So the idea is, you take the plain text and you compute the MAC of the plain text and then you sort of combine those together and encrypt both.
Another way to do it is called encrypt then MAC. This is used by the IPsec protocol for, like, yeah. So we have plain text. What we're gonna do is encrypt it first, and then we're going to calculate the MAC of the cipher text.
So the third way, which is used by SSH, we take the plain text and we encrypt it. Then we get the cipher text and then we take the original plain text and we compute the MAC of that, and then we put the cipher text and the MAC of the plain text together. So which, which of these sort of three
standards or three approaches got right? Anybody want to take a guess which of these is actually the right way? None. There is actually a right answer. One of them did get it right. So the answer is encrypt then MAC used by IPsec. So why?
What's wrong with these other methods? So SSL, TLS, you might remember there is this attack called Beast. It's using something called a padding oracle. I didn't really go into how padding actually works, but it's how you deal with, when your plain text isn't actually aligned to a block.
So using Beast, they were able to get a little bit of information out of when it decrypts and it does this padding check, and you can tell if it got through the padding or not before it hit the MAC. So the solution TLS uses now is to make sure it always checks the MAC even if the padding fails. So it's a
little bit of a band-aid. Encrypt and MAC, used by SSH, is vulnerable to chosen ciphertext attacks. There's a fun little paper on this. Fortunately, the SSH protocol was extensible enough they managed to avoid, they managed to effectively fix
this retroactively. So in review here, if we were trying to build our own authentic encryption scheme, what we have so far is we're using AES in CBC mode, since Ruby open SSL doesn't support counter mode. We're gonna do the IPsec thing and encrypt in MAC, and I chose HMAC. HMAC is
really nice because it takes a lot of the sharp edges off of some of the other MACs. So what this actually ends up looking like is what's in Rails, the active support message encryptor. So this is definitely a cool thing to use if you just need to encrypt something and you're using Rails. It's definitely a way to go.
So let's talk about what else could go wrong. Not done yet. So the next thing is timing attacks. So speaking of that active support message encryptor, it used to be vulnerable to these. So this is a patch by coda-hail to implement a constant time
comparison of a MAC. And the problem is, if you don't do this, the attacker can use this sort of like infinitesimal timing information, especially if they're on the same LAN as you or on the same host, to just try to guess at the MAC a byte at a time. So you see before what it was doing
was not equals. So the problem with not equals is it'll sort of fail fast and exit early as soon as it sees something that doesn't match. So by using the timing information off of that, an attacker can effectively guess the MAC a byte at a time. So the solution is all that
nonsense you see down there at the bottom where they're doing XOR between the two bytes and doing or equals and doing this over all the bytes and then looking at the actual value of the result. So this is all pretty crazy stuff, right. And we haven't even talked about pubkey. So really I
don't think amateurs should be trying to put all this stuff together. Unfortunately that's sort of been the state of the world in Ruby. So what can we do better? We can have more boring crypto constructs. So what, what qualifies
as boring? Well, to do that, let's talk about what isn't boring. So this has been how most things have worked in the Ruby world. So OpenSSL is kind of the terrible library to begin with. And then pretty much every Ruby gem you see that deals with
encryption just layers on a bunch of amateur code. Trying to put all this stuff I just described to you together. And typically it'll get at least one thing wrong. So I'm not gonna name any more names besides that fast AES gem, because I think that one was just pretty crazy and dangerous. But pretty much every gem out there, if you
go through and you try to look for all these things and make sure they got it all right, it will generally get something wrong. Oftentimes they will not use a Mac at all, so they'll just use encryption and the attacker can screw with your cipher text. And then there's all sorts of other little things that they can get wrong, which I didn't even
cover here. So the boring approach, in my opinion, is to use a crypto library written by cryptographers. And when I talk about a cryptographer, who am I talking about? And it isn't someone like me, right. Like, I'm a crypto enthusiast, but I'm not a cryptographer. I
cannot design my own ciphers that will be secure yet. I can't. Something I aspire to, maybe, but not quite yet. So what we really want is to bind to a library that was actually written by cryptographers. People who spend all their time thinking about these kinds of attacks.
So I have written a library like this that is actually a FFI binding to an actual library written by cryptographers. So the name is, unfortunately, a little bit confusing. I call it rbnacl. But you may also know there is Google Native Client. It
is an ACL organization that, in Japan, that you might be familiar with. It isn't that. So this is a library by this guy, Dan Bernstein. You may know him for libraries
like, or projects like Qmail, DJBDNS, and DemonTools. And if you haven't been paying attention to him for the past decade or so, what he's really gone hardcore for is cryptography. So he has designed quite a few of his own ciphers, and all
sorts of algorithms, and created this NaCl library, which is slowly getting a little bit of popularity. And you see the URL down there. It's under the cryptosphere organization slash rbnacl. So to make things even more confusing, this isn't actually binding to NaCl. It's binding to a portable
repackaging of NaCl called libsodium. So the best description I've heard of this is it's de-Bernsteinized. A lot of, a lot of people don't like DJB's build system, and it's kind of crazy, cause the way it works, once you've built the library, it's completely
non-relocatable. So you can't really package it as a binary for a distribution. So libsodium took NaCl and added a standard automake-style build system. So it's easy to install. It is in mac ports, and you can install it with brew install libsodium. There are packages
for various Linux distributions. Some of them you'll have to actually build yourself from source, but the basic work is there, and it's getting more and more widespread option. So NaCl has many primitives. I'm only gonna talk about two here. So these are the symmetric and
asymmetric encryption I was referring to earlier. But it also has a ton of other stuff. So it has HMAC. It has digital signatures. It has all sorts of fun stuff for elliptic curve cryptography. So I definitely recommend checking it out. You can
go to the rv-naCl wiki and it has all the features listed out for you. So first I'm gonna talk about the symmetric encryption primitive it provides. So this is authenticated symmetric encryption,
and it is called secret box. This may be a little hard to see, but it should be fairly straightforward to follow, I hope. So what we're gonna do is we're gonna make a key. That is the size of a secret box key. It's actually 32 bytes. So we get
a random key, and that is using rv-naCl's own random number generation on Unix-like operating systems that pulls from dev view random. And on Windows it uses, I forget what it's called. Yeah. Windows. Anyway. It
So after we've done that, we're gonna make a new secret box with the key. And then here's the fun part. We need to make a nonce. So this is just generating a random nonce of the secret box's nonce
bytes length. There's also another feature in rv-naCl called random nonce box that'll do all this stuff for you. The important part is a nonce is a single use value. So every time you encrypt something with this box, you need to make a new nonce. So it doesn't actually have to be random. It could just be a counter.
A nice thing about it being random is it's long, so it's 24 bytes. So if you just do a random number every time, it's hard to screw up. You don't need to keep track of the state of how many nonces you've used. So after that, you hand the nonce and
the message to the secret box. It'll make the cipher text for you. And to decrypt it, you get the same nonce and the cipher text and it will decrypt. And behind the scenes, this is doing all that authenticate encryption stuff. So it's adding a mac, it's checking it, and it's using encrypted mac. And then down there at the bottom, you see
if you try to open the box and something is wrong, either the nonce is wrong or the cipher text has been corrupted, it'll raise an exception for you reliably. So this is using a couple algorithms designed by Dan Bernstein. So the encryption cipher is called XSalsa20.
And the mac is called Poly1305. So probably right now you're thinking, what the hell is XSalsa20? Like, never heard of this. That, that can't be boring, right. So I think this is boring because it is a cipher that has sort of been standardized through this contest in Europe called Ecrypt. And the
goal of Ecrypt is sort of like when A, there was the AES contest. They were trying to produce better stream ciphers. So the XSalsa20 cipher was one of four they selected for inclusion in what they call the Estream portfolio. I say this is boring because things have gotten
very not boring in the cryptography world lately. You may have heard NIST standardized a random number generator designed by the NSA called Dual EC DRBG and turns out that thing had a backdoor.
So there's still open questions about the NIST elliptic curves as well, and whether or not they contain possible NSA backdoors. I mean, if you're asked me my layman's opinion, I'd say it's probably unlikely they backdoor the NIST
elliptic curves. But it's hard to know, and I think the boring thing is to use ciphers that are beyond our approach. So to take, to do asymmetric crypto using these same sort of primitives, we have this thing called
box. And here is an example of how to use box. So this time we have to actually generate a random key. So this is using that elliptic curve stuff I was talking about earlier. I'll get into how that works a little later. So we take a private key, and unlike
RSA with elliptic curves, we can calculate the public key from the private key. I think I spot typed it there. Awesome. Oh no. So yeah. So once we've done that, we have a public key, and you'll notice here when we
make a new box, we're giving it both somebody else's public key and our private key. And the neat thing about this is it's performing something called mutual authentication. So all these boxes are based around a set of keys. It's who you're sending the message to and your private key. So
that way, when somebody opens up the box, they'll know they got it from the right person. So we make a new box. They'll also have a box on the other side. It is effectively the same box just computed from the reciprocal keys. So then after here it's
pretty straightforward, just like this symmetric crypto. So what we're gonna do is make it nonce again. We have the message and we're going to encrypt the message under that nonce and under that pair of keys. We get a cipher text again, and then the person on the other side can open
it. And once again, like before, if it has been tampered with, it will raise an exception. So box is built on the same primitives as secret box, so it's still using what's called the Pulsa 20 cipher in the Poly 1305 Mac. The main difference here is we're adding in a defeat-hellman function. So that is called Curve
25519, and that is an elliptic curve algorithm designed by Dan Bernstein. So one of the big worries about elliptic curve cryptography, in addition to possible NSA tampering, has been patents. So DJB has designed
this curve specifically to sidestep all the patents. It's pretty awesome if you go to the website for it. He lists out the patent, and he lists out the prior art basically saying this patent is bullshit anyway. But then he's like, here, I completely avoided that problem entirely.
So really quick, here's how defeat-hellman works. So it's pretty simple. What we do is a thing called scalar multiplication. So we take Alice's private key and perform a scalar multiplication operation with Bob's public key, and we get a shared secret.
And Bob is able to calculate the same secret by multiplying his private key by Alice's public key. So these two, two operations are sort of like a reflection of each other. So secret, box works by taking that shared secret and using it to
drive a symmetric key. And that's all I got. Keep it boring.