 Yeah, so Jose on the left or Josie on the left is actually a set of standards RFCs and Jose is my particular implementation of them We'll be using this terminology to disambiguate throughout the talk So whenever I say Josie, I'm referring to these standards and whenever I say Jose I'm referring to my implementation of those standards so Josie stands for Jason object signing and encryption and And It is a set of standards For formatting all sorts of cryptographic related stuff in Jason format now some of you are probably wondering why we need someone new standards and There's actually quite a few reasons for this For those of you who've been doing cryptography at all You know that our standards have grown up organically over time So we started off, you know with with various different Here's how a key works and then we started doing encryption and various other things But it got really really hairy quickly because for example, what sort of format do you store your certificates in? What sort of formats do you store your keys in all of this stuff? Is everyone did sort of their own thing and so as an example GPG, you know is not the same as open SSL for example So we also had need for some for doing cryptography in the web space and in particular for Bundling cryptographic data inside URLs, which is the one of the driving forces of the standards and So what we actually have here is the first cryptographic system that integrates all of the different parts of what we would today call a crypto system into one usable system where everything sort of works with everything else and And we're gonna walk through how exactly this looks We're gonna start off with a really really simple example This example is just a symmetric key. We call these Jason web keys or JWK for short a Jason web key when it's a symmetric key looks just like this We have on the top the KTY parameter, which just simply specifies what type of key. This is in this case It's octets so we should expect that it's going to have a K parameter and the and the K Parameter is going to contain the actual octets of the key These are base 64 URL encoded and then we also in this example have an optional value That does not that is not actually required but can be present for a variety of different keys And in this case this value is the algorithm parameter and this indicates what algorithm that this key can be used in are used with and So this is pretty much the simplest example We're going to see on the set of slides notice that This same pattern of representing binary as base 64 data is going to be universal throughout the the all of the Josie Specifications any questions about this? I hoping this one is pretty straightforward Okay, let's let's move on to a little more complex example So this is also a JWK same data format But this time we're representing not a symmetric key, but we're representing an elliptic curve key in this case We also have the key type KTY at the top exactly like the last one. This specifies EC. This is an elliptic curve key We next then have the four required parameters for an elliptic curve key The first is the name of the curve that we're actually representing in this case This is a p256 key for those of you who are not familiar with elliptic curves P256 is one of the standardized curves that's used by NIST it's one of the most widely available and It's one of the ones that's standardized in in Josie Next we have three parameters x y and d Because Keys are points public keys and elliptic curve cryptography are points on an elliptic curve We have an x and a y value which indicates where it is on the curve and the d value is the private value or the secret value so So these are these are this is a full public and private key you all in all in one JSON object Finally, we have two more optional parameters and Notice that these are different optional parameters than ones we saw in the previous slide In this case, we have a key use and this is allowed to be used for encryption and finally we have a KID parameter and this is just a unique identifier for key. It can actually be anything you want But it's pretty common to see the KID actually be a thumbprint of the key But it can actually be any any string that you want and I'll explain more about what thumbprints are shortly Any questions before we move on? So from here it gets much more complicated because we are now moving into RSA keys RSA keys, you notice they still have the same KT Y parameter at the top this indicates what type of a key this is and We have the next what is it seven parameters or the RSA parameters actually eight are the RSA parameters so from here all the way down to here and The specific details of those I won't go into so if you want to know more about RSA keys There's lots of information on the on the interwebs and you can find it there Lastly, we do have two more optional parameters here in this case We have the algorithm, which is like what we saw with the symmetric key This is allowed to be used with the RS 256 algorithm, which is a Force signatures and it indicates that the data should be hashed with shot 256 And then the hash of the data should be signed with with the RSA key And then finally we have another KID parameter you notice this time It's a date when the previous example We just had the number one which in this place is cases like a serial number for keys that have been generated over time In this case, it's the dates in which the key was generated Again, this can be anything that you want. It's as long as it uniquely identifies the key according to what's whatever system you're using So those are the three main key types that are used in the Josie crypto system There's actually another one that has just recently been standardized, which for those of you who are Doing cryptography in a day-to-day basis. This is the CFRG curves So things like ED 25519 and ED 448 have both recently been standardized as key types as well one last thing that we should note is that Josie actually standardizes a way to represent sets of keys as well Which is something we don't see in pretty much any other crypto system So you can actually define a bundle where you have this object and you have a parameter called keys And it's just simply an array of keys, but there's also extra parameters that you can put in here Moving on to performing a signature. This is actually the most complex example of a signature that we'll see today So at the very top we have our payload. This is the data that was actually signed So whatever the message is that you want to sign is put into the payload and again base 64 URL safe base 64 encoded and Then we have an array of signatures. We have two signatures in this JWS. So here and here Each signature Has a protected header now the protected header as you can see all the way on the right side Over here. We actually have this object And that indicates the contents of what's inside the protected header that Structure is then base 64 encoded and included in the protected header We have another value called header which is not protected and what this what we mean by protected and not protected by the way Is that the protected header if it's modified the signature will fail to validate? But the the header that is not the protected header can be modified and it doesn't invalidate the signature Finally, we then have the signature that is a signature over the payload and the protected header So this is the most complex example if you this is also called by the way J a general serialization and It's called general serialization because basically any time you have more than one signature in a JWS You have to have this array like this but if you have a case where you are only ever going to have one signature you can actually use another serialization called flat and And the way that the flattened serialization works is it just basically takes all of the data from that One serial or from that one signature and moves it up in the object hierarchy So if you go back, we have protected header and signature here And then we have protected header and signature here So it just moves them up in the hierarchy and takes up a little less room And so you notice here by the way We're saying in the header We have a key this is the key that was used to sign it So some if you were to receive say this JWS you could go look in some key repository for This particular key ID and that's the one that should be able to validate the signature however, there's also one more serialization and What we're going to do if you remember we've got We've got four items here now We're going to leave off the header parameter Which you remember is not protected so it could be modified and we're going to take just the signature the protected header and the payload and We can flatten this once again Into a string Where you just simply put the protected header contents followed by period followed by the payload followed by period followed by the signature Now the unique thing that we can actually do with this is we can put this in a URL So one one particular case where this came up was we were having a meeting Where we wanted to have a registration system. So people could sign up with their email address and it would send them an email to confirm their email and And then they would click the link of course you've done this a million times on the internet not not if you know what I'm talking about, right? so Basically, I came into the meeting about three minutes late and they had already designed the whole thing and it was Magnificent there were like multiple moving parts and there was databases and all sorts of stuff just for this registration system And I came in and I sort of raised my hand and I said Why don't we just sign their email address and send it to them in a URL using this using this data format? And you don't actually have to have any state on the server because once they click the link the server just validates the Signature you don't need to have databases. You don't need to have all of this massive code It's just really simple and effective, right? So this is this is one of the one example of how the Josie standards can be used very effectively And Since Josie always uses URL safe base 64, which is just like regular base 64 But two characters are different in the encoding so it is standardized, but it's but it's slightly different than regular base 64 Since Josie always uses your else the URL safe base 64 and then always uses periods to concatenate the fields This is always safe to be inside a URL We can do the same thing with encryption. So the last case we were talking about signing and now we're going to talk about encryption This this is the most complex example. You'll see today Because encryption is slightly more Complicated than than signing. So the way that encryption works is You are going to have an encryption key and that encryption key is going to encrypt all the data And then you're going to encrypt the encryption key using another key And that key in this case we call the recipient key So if I'm going to encrypt something to you and to you and to you I only need to encrypt the content one time and then I encrypt that one key to each of your own separate keys Right and each of you are recipients and that's exactly what we're looking at here so in general format we have The first thing we have is the protected header at the top here, which is just like the signature So it uses all the same mechanisms that we saw in a signature, but it's but it's now being done for encryption We have an unprotected header protected header by the way if you remember means that if you modify it Then the decryption will fail But the unprotected header can be modified after the fact and decryption will not fail Same encoding over here. So the protected header is actually in this format and then it's It's serialized into a string and then basically foreign coded and put into this protected header After this we have the ID the initialization factor for the cryptography We have the cipher text itself Which is the plain text that we've now encrypted is stored here as cipher text And then we have a tag and the tag is the thing that validates that when we decrypt it it hasn't been modified So that gives us our authentication So all of this is basically we take the data in we generate an ID and that's stored here We encrypt the data using using a randomly generated key that comes out of cipher text We do our authentication which produces a tag you stick the tag on there We write our parameters into the protected header and then finally we take that key that we used to the encryption And we encrypt it to the actual recipients, and here's the recipients. We have two of them here one and two and a recipient can have a per recipient header, which is not protected and Then when we were encrypted to the recipient We're encrypting the key that we used to encrypt this and that encrypted key is stored here and Then we also have some optional parameters here like which algorithm was used for the encryption We have things like which key ID should be used to decrypt this value and so on So this is the most complex example. I've probably hurt your brain a little bit But we're going to move on and we're going to get more simple from here So hopefully it should be simple to understand If you remember we also had for the Jason Web signatures We had a flat syntax Which is where when you have a single a single signature You can just move all the contents upward into the object hierarchy, and we have exactly the same thing here So if we go back, you notice we have two recipients here and the important bits are that we have an encrypted key Well in this case, we also have a cryptic key and a header So if you have a single recipient You can create the same object, but instead just put the encrypted key in the header in the parent object And there's an implicit recipient there Just like Jason Web signatures. We also have a compact format So we're going to come back here. We have a protected unprotected IV cyber text and tag No, I'm sorry protect these are the five we're gonna take protected IV cipher text tag and a cryptic key Initialization vector Yeah, it's basically a bit of random data to ensure that encryption is unique for each encryption operation It's it's a public value But it's used. It's the very first value you put into to get a starting position in your cryptography so And it's used pretty universally although it's used slightly differently depending on the algorithm you choose for So for example, if you're using AES GCM It will be slightly different than if you're using AES CBC HMAC Yeah Yes, so tag is The it's the authentication information for for the cipher text So after you encrypt the data then you perform authentication on the cipher text to make sure that it's not modified So the tag indicates For wanting let me give you a concrete example of this in the algorithm AES CBC HMAC the actual encryption is done using AES CBC and then an HMAC is done over the entirety of the cipher text and The output from the HMAC is stored as the tag Now when you go to do the decryption The first thing you do is you validate that the cipher text you you run that cipher text through the HMAC again And the HMAC will output a value if that value doesn't match this Then the cipher text has been modified and you absolutely should not do anything with it. You should drop it to the floor Does that help? Yes, another question. Oh Sorry, yes, I should do that that question was can I explain what the tag parameter is? It is the tag parameter the question is was the tag parameter used for something for algorithms other than HMAC The answer is yes For example, if you're using AES GCM the tag is yielded as part of the encryption operation So in that case, it's all done as one step The plain text is input to AES GCM and the cipher text comes out And then when you're off completely finished the last block of cipher text comes out and the tag comes out But it's all done as a single operation. Yes The tag is an output during the encryption phase and it's an input during It's an input during the encryption phase and it's in no I'm saying that's wrong start again Okay, the tag is an output during the encryption phase and it is an input during the decryption phase Yeah, yep, and the the important thing of the tag is that it's validating that that the actual message has not changed Right because there's all sorts of attacks if somebody can get a hold of your cipher text and and make changes to it and ask you to Decrypt it There's all sorts of attacks you can do so the very first thing you want to do is validate the message has not been modified Once you know that it's not been modified then you proceed with decryption in the case of AES AES CBC HMAC. Yes, it is a digest in the case of other algorithms. It is not it's sort of a generic remember this is really In this particular case the JWE standards. We're not actually defining how the algorithms work. We're defining the storage format and Tag you can be used in different ways by different algorithms, but it does roughly the same thing for all of them So another question. Yes, sure It is not. Yes, the question was is the tag also encrypted? The answer is no In the case of the algorithm AES CBC HMAC, which is one of the algorithms defined by the Josie standards You actually generate a double length key. So instead of 16 bytes you would generate 32 the first half of that key is used for doing the encryption The second half of that key is used for doing HMAC. I may actually have my haves backwards But it's it's one of those two. So basically you generate a double size key and One is used for HMAC and one is used for for the actual encryption for AES GCM That's not the case. You use the same key for the entire operation. Any other questions? Okay So we already talked about having compact format which can again be used in URL So if for example, you wanted to have some date Maybe that you see some data excuse me some metadata that you store sale like in a cookie and you want to store that on A on a client system You could use this actually if you wanted to put it in some kind of a URL Like sending it in an email or something like that and you could actually bundle in encrypted data along with the URL the next Data format we're going to talk about is the JSON web token and a JSON web token is the closest analogy is That it's the metadata that you get usually in a certificate particularly In the for you know for the if you're using a user certificate This would be similar kind of data that you would get in that certificate So there's no actual cryptography involved in this. These are just the standard parameters that are well defined And then there's also in the standard a way to put your own data in here it basically says that either you should define a standard and publish that standard and then you can actually have a Short name reserved for you or if you're doing something that's application-specific then you should use a a Conflict-resistant format so something like you know calm dot example dot parameter foo And that would that would be sure not to collide with other people using using the same thing We'll just walk very briefly through what these are so the issuer is the person who is making the assertion So they're saying I'm vouching for the subject which is me and Pima column and the recipient for this is dev conf that's you guys and this assertion will expire at this particular time and it's not valid before this particular time and it was issued at this particular time and Finally JTI is something that I forget my head. Yes. Thank you. It's the token identifier Yeah, so this is a just is like the key the KID parameter for keys But this is a unique identifier for this for this web token Now what's interesting is not the web token itself, which again has this defined information There's also some additional stuff that's been defined since this point Which could be put in here and then you can add your custom data But that's not the thing that's unique or that's not the value itself Well, the value of this is that you take this metadata and then you wrap it inside either a jwe Jason web encryption or a JWS adjacent web signature So this is the way that you can cryptographically validate that this data is actually not modified And that it's who it's supposed to be and that only the person who's supposed to see the data can see it One of the things I don't like about the standard but is is well-defined is that the JWT can be wrapped in Jwe's or JWS JWS is and possibly recursively so this means that you can actually pass the data across multiple hops and You know every hop could say add its own signature or it could add encryption at various different layers and then when you receive it you basically need to unwrap all of the layers and And then you actually get the data at the end once you've validated every single layer So it's a little bit complicated and I haven't written code for this because it's hard. Yes, correct So it does have some positive uses. I only don't like it because it's actually just hard to implement and I haven't implemented it yet Okay, so we've up until this point. We've been talking about Josie, which is the set of specifications So everything before this you know this slide and before it should be standard everybody should be doing it exactly the same way and Everything that you see after this point is now talking about the specific implementation that I've done So we have at Red Hat created the Jose project the Jose project as a C library and a C li implementation of the Josie specifications, so We have support for all of the RFC defined algorithms this statement is actually out of date because the CFRG curves were just recently standardized but up until that point we have all of the algorithms and One of the neat things about this library is that we actually don't have any C data types natively So what you and we have no date Jason parsing why this is important first of all, let's talk about the parsing Parsing is really dangerous. I don't know if you watch CVE's There's a lot of them for parsing bugs, right? And what you really don't want to have is your parsing and your encryption in the same place, right? That would be just absolutely a fundamental fail and in fact a lot of Implementers of Josie actually absolutely make this mistake They take strings as input strings as output and they serialize everything So so I want to point out specifically we do not do any Jason parsing there is a really good library called Janssen and Janssen is really battle-tested and it works really well and That is who does all of the parsing and it can be done In another in another thread if you wanted to and it does not have to be related to to Jose at all But you pass us those parse data types But it's also further important to note that we don't then take those data types from from Janssen and convert them into something C native and the reason for this is that actually a lot of implementations do this They make the mistake of saying well You give me something that's Jason and then I'll parse it into a language structure And then we can operate in the language structure and then when we're done We'll serialize it back out as Jason well the problem with this is that the standards are intentionally designed to be Extremely fluid in the amount of optional data that you can have and so what all the people do wrong when they implement This is they parse that into the C C type and anything they don't know about they drop on the floor Well now you've just completely lost all of this extensibility And we don't want to do that so what we do is we don't have any native C data types You just parse the raw Jason and once you have a raw representation of that Jason you hand it to our library and we do everything from there Our API is also driven by a template approach. So what this means is that? Instead of having again native data types, which specify all of your options You just hand us something that looks like the output you want So for example if you're generating a key tell us what algorithm you want that key to be for and then hand us that and The way that you tell us what algorithm is going to be for if we go all the way back to the JWK We have an algorithm parameter, right? So give us a Jason object that has only leave out all of this data has only the algorithm parameter And we'll fill in all this data for you automatically, right? So it does require that you know a little bit about the specification in order to craft this template But it also means that we don't have to do all sorts of overhead when Manipulating these data types so it can actually be you basically just parse the data give us the data directly, and then you're done Whenever we have missing parameters in these templates We do our best to fill in the data first of all we infer for example algorithms from keys If you don't tell us what kind of algorithm that you want to use for your encryption And you've handed us a key that has the algorithm parameter. Guess what? We can figure out exactly which algorithm you're trying to use and we can do this without any ambiguity One of the things that's important is that if we do detect the ambiguity or a conflict we bail But if we don't if it's very obvious what you're trying to do then we just do it for you so any All the parameters are inferred from keys They're inferred from the headers and we always if they're not specified use sensible secure defaults Yeah Yeah Specify It will figure out things it can figure out so if you don't have an algorithm we can't fill that in for you But if you give us the algorithm we can fill in all of the other information that the algorithm implies right And so the library design works like this We have a very core library that implements the Josie logic And then all of the crypto itself is implemented as hooks Which means you can plug in another crypto system here at some point if you want and then all of our All of our code is currently using open SSL so we're not we're not building the the algorithms are directly and Then on top of the C API we provide a CLI tool Which provides a thin layer around the C API and what this means is that anything that you can do essentially and see you can also do from the command line The last thing is that we extensively unit test this against all of the test factors from the from the RFC We also use test factors that have been produced by other parties as well And we're fully conformant to all of those So here's the URL for the project github slash github com forward slash latch set forward slash Jose And it's really easy to install on fedora just DNF install Jose So let's look at how to actually use the Jose code Three minutes. Oh goodness. I'll go quickly. So if we have a function called Jose JWK gen It takes a configuration object, which can be null and any J JWK template you want you just tell it basically I want a key for this algorithm and then it spits out that key generates it for you You can also specify things like I don't want this algorithm specifically I just want 16 bytes and you can do that and then lastly if you specify multiple templates We will output a key set if you remember there's a key set Data type and so if you just get tell us generally multiple keys will output it as a set By the way anything that you put in this object in this template That that we don't know about we leave it in place. We don't touch it JWK so we have some JWK utilities the we have Pub which removes all private key material We have a Use parameter Which basically says hey, can I use this key to do signatures? Can I use it to do encryptions and it will tell us yes or no and then finally we can generate a thumbprint? From the from the public key material We have algorithms for signing And we basically just an algorithm the C code is here by the way and the CLI code is here Anything you can do with the CLI you can do with C and vice versa. I think there's only one exception to that Basically most of these parameters are null so Typically if you're doing a signature the config parameter will be null the signature will be null and you'll say here's my Over my JWS output is and this is the key. I want to use for the signature So but if you want more control you can fill in the other fill in the other data Verification is basically done the same just in the opposite direction of course and Here we do oh one thing I need to say here is that if you specify multiple keys We give you general if you do one key we give you flattened serialization if you specify the dash C option we give you compact serialization and The last thing is that you can actually create a signature that does not contain the the payload in it It can be contained in another file if you want to So verification is basically the same thing Just the other side of the of the signature and we have a non-zero agnus exit status here and zero exit status here Here's a case where we have detached payload. So it's not actually in the object itself Same thing with encryption You can do Multiple keys you get generalized serialization one key flattened serialization this dash C option gives you compact serialization and One of the downsides by the way to encrypting or to encrypting or signing data with with The Josie standards is that for example all your cipher text if it's a big cipher text It's not gonna be base 64 encoded which makes it even bigger Which is why you would want to use this detached serialization Detached serialization is going to output the cipher text is binary and all the other parameters are just going to be inside your case There's other stuff here that's cool Let me just say this we're working on adding pkcs 11 support We would love to have additional crypto library support We don't have any jason web token functions yet, but if you want to add those please contribute We also would like to add the functions to convert from certificates And we'd like to add any other rfc features of course poll requests are welcome And if you have any questions, I'm happy to field those do we have time for questions? Okay, thank you I'll hang outside the door if you have questions just come grab me