<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Scott Brady</title>
    <description>The latest articles on DEV Community by Scott Brady (@scottbrady91).</description>
    <link>https://dev.to/scottbrady91</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F131470%2Fadbaf03f-c0e6-47ef-9d68-26bc4478f349.jpeg</url>
      <title>DEV Community: Scott Brady</title>
      <link>https://dev.to/scottbrady91</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/scottbrady91"/>
    <language>en</language>
    <item>
      <title>OAuth is Not User Authorization</title>
      <dc:creator>Scott Brady</dc:creator>
      <pubDate>Fri, 11 Dec 2020 12:02:21 +0000</pubDate>
      <link>https://dev.to/scottbrady91/oauth-is-not-user-authorization-7e7</link>
      <guid>https://dev.to/scottbrady91/oauth-is-not-user-authorization-7e7</guid>
      <description>&lt;p&gt;In the same way that &lt;a href="https://www.scottbrady91.com/OAuth/OAuth-is-Not-Authentication"&gt;OAuth is not authentication&lt;/a&gt;, it &lt;strong&gt;also does not tell us what the user is allowed to do or represent that the user can access a protected resource&lt;/strong&gt; (an API).&lt;/p&gt;

&lt;p&gt;Understanding what OAuth is not is just as important as knowing what it is, in order to use it effectively. In this article, I’m going to discuss how OAuth does not include user authorization and why user authorization rules should not live within your OAuth authorization server.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TL;DR: OAuth is not suitable for user authorization. The fact that you have an access token that allows you to act on the user’s behalf does not mean that the user can perform an action.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Client Authorization (Delegation)
&lt;/h2&gt;

&lt;p&gt;OAuth is an authorization protocol, but maybe a better name for it is a delegation protocol. It is a protocol that allows a client application to request permission to access a protected resource (API) on the resource owner’s (the user’s) behalf.&lt;/p&gt;

&lt;p&gt;Let’s take a look at the authorization process:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The client application asks the user if they can access a protected resource on their behalf (by redirecting the user to the authorization server’s authorization endpoint, specifying exactly what they would like to access (scopes))&lt;/li&gt;
&lt;li&gt;The user identifies themselves to the authorization server (but remember, OAuth is not authentication; you’ll need OpenID Connect to help you with that)&lt;/li&gt;
&lt;li&gt;The user authorizes the client application to access the protected resource on their behalf (using the OAuth consent process)&lt;/li&gt;
&lt;li&gt;The client application is issued an access token&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;An access token represents that the client application has been authorized by the user&lt;/strong&gt;. The protected resource can look at the access token and say, “okay, Alice authorized this application to access these parts of my system on their behalf; I’ll let it through”. However, &lt;strong&gt;just because Alice said it was okay does not mean that Alice is authorized to access the protected resource&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Client Authorization vs. User Authorization
&lt;/h2&gt;

&lt;p&gt;Let’s break that down, using a banking system as an example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Client authorization:&lt;/strong&gt; can this client application read Alice’s transaction history?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;User authorization:&lt;/strong&gt; can Alice view the balance of account #123?
OAuth can handle client authorization by issuing an access token that Alice authorized. OAuth cannot handle user authorization.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Open Banking &amp;amp; FAPI introduce &lt;a href="https://tools.ietf.org/html/draft-ietf-oauth-rar"&gt;Rich Authorization Requests&lt;/a&gt; (RAR), where a client application can ask the user to authorize a specific transaction. But again, this is about the user consenting to the transaction, as opposed to what the user is allowed to do.&lt;/p&gt;

&lt;h2&gt;
  
  
  User Authorization Rules in your OAuth Authorization Server
&lt;/h2&gt;

&lt;p&gt;Hopefully, it’s now clear that an OAuth access token (or an OpenID Connect identity token for that matter) does not represent the user’s permission to do something. But what about putting user-level authorization rules within your authorization server? After all, you already kind of have that with the user authentication process.&lt;/p&gt;

&lt;h3&gt;
  
  
  User-level authorization during authentication
&lt;/h3&gt;

&lt;p&gt;This is where I am happy to give some ground. Confirming that the user is authorized to use your system when they authenticate is perfectly acceptable. For example, has the user been disabled by an administrator? Do they still qualify to use your services?&lt;/p&gt;

&lt;p&gt;If you decide that the authenticating user is not authorized to use your system, you simply do not let them log in. These kinds of checks can also be performed during token generation or maybe as part of token validation (think of the introspection endpoint).&lt;/p&gt;

&lt;h3&gt;
  
  
  User-level authorization based on request
&lt;/h3&gt;

&lt;p&gt;What breaks this is when you try and add user-level authorization per client application or protected resource. For instance, is the user permitted to use this scope? Are they permitted to use this client application (while OAuth is not authentication, you may see this check when using OpenID Connect)?&lt;/p&gt;

&lt;p&gt;This would make your OAuth authorization process look like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The client application asks the user if they can access a protected resource on their behalf&lt;/li&gt;
&lt;li&gt;The user identifies themselves to the authorization server&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The authorization server decides if the user is authorized to access the client or protected resource&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;The user authorizes the client application to access the protected resource on their behalf&lt;/li&gt;
&lt;li&gt;The client application is issued an access token&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Adding another Access-Control List (ACL) to your authorization server can’t be that bad, right? After all, it is an authorization server!&lt;/p&gt;

&lt;p&gt;In my opinion, this is &lt;strong&gt;brittle and prone to error&lt;/strong&gt;. You are now back to relying on the fact that tokens were issued to represent that the user and the request have been authorized, which is not something OAuth was designed for and is a dangerous assumption to make.&lt;/p&gt;

&lt;p&gt;Just as many attempts to use OAuth to represent user authentication have failed, I’ve seen the same happen with user authorization too many times. The protocols just weren’t designed for it, and it’s just too easy to get wrong, especially when your token issuer is also providing SSO, issuing tokens without user interaction.&lt;/p&gt;

&lt;p&gt;You are likely using a framework or out-of-the-box solution as your OAuth authorization server, which will want to follow the OAuth specification and issue a token to the authorized client application. &lt;strong&gt;You’ll spend your time fighting the design of OAuth&lt;/strong&gt;, and if you make a single mistake or misunderstand how your framework of choice works, then the authorization server will kick in and issue the token as the user and client have requested, just like it is meant to.&lt;/p&gt;

&lt;p&gt;I know I’m blurring the lines between OAuth and OpenID Connect a little here, but here’s a Stack Overflow question that I think highlights the kind of bizarre scenario you could find yourself in:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“I am looking [for] a way for [my authorization server] to invalidate the submitted token if the user doesn’t have access to the application in a single go, even though the challenged token might be valid if it is submitted by other application which the user has access to”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;While you initially wanted to have all of your user authorization rules live within your central OAuth authorization server, you will likely end up duplicating these checks into your client applications and APIs to solve these kinds of problems. You are probably going to code yourself into a corner.&lt;/p&gt;

&lt;h2&gt;
  
  
  User Permissions in your OAuth Authorization Server
&lt;/h2&gt;

&lt;p&gt;This is where most of my customers end up after understanding that user-level authorization is not part of the OAuth protocol and that it is not an easy fit within their OAuth authorization server. But the desire to write all of their authorization logic and user permissions in a single place still exists, which is understandable, especially when they have already achieved that with authentication and API access by using an SSO solution that implements both OAuth and OpenID Connect.&lt;/p&gt;

&lt;p&gt;So, what is the solution? Role-Based Access Control (RBAC)? Stuff tokens full of user permissions?&lt;/p&gt;

&lt;p&gt;Well, that is a story for another day and well outside of this OAuth story. I recommend checking out Dom’s excellent article on how &lt;a href="https://leastprivilege.com/2016/12/16/identity-vs-permissions/"&gt;identity and permissions don’t mix within an SSO solution&lt;/a&gt;. For solutions, take a look at how &lt;a href="https://www.identityserver.com/documentation/enforcer/alfa/IntroducingAlfa/"&gt;authorization languages are evolving&lt;/a&gt; with ALFA and how you can create authorization policies in a single place that are readable by non-developers.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Random Stuff
&lt;/h2&gt;

&lt;p&gt;This article would not be complete without collating some of the weird and wonderful loaded questions I have received on Stack Overflow or my blog. These are often followed by a “gotcha” or a “checkmate”, or sometimes even a personal insult. But I’ll let your imagination come up with those.&lt;/p&gt;

&lt;h3&gt;
  
  
  “Then why is it called an authorization code?”
&lt;/h3&gt;

&lt;p&gt;The authorization code represents the user authorizing the client application on their behalf. Again, that is client authorization, not permission to add user authorization.&lt;/p&gt;

&lt;h3&gt;
  
  
  “Then why do people return 401 Unauthorized when you don’t have a token?”
&lt;/h3&gt;

&lt;p&gt;Naming is hard. In this use case, it would be nice to have named this status code “Unauthenticated”, but at least RFC 7235 requires that you include a &lt;code&gt;WWW-Authenticate&lt;/code&gt; header alongside this status code.&lt;/p&gt;

&lt;h3&gt;
  
  
  “Then why is it called the Authorization header?”
&lt;/h3&gt;

&lt;p&gt;Again, naming is hard. Basic Authentication also uses the Authorization header, but that doesn’t mean the user has full access or is even allowed to use the application. You still have to check if the user is allowed to perform an action.&lt;/p&gt;

&lt;h3&gt;
  
  
  “Then what are scopes for?”
&lt;/h3&gt;

&lt;p&gt;Scopes represent a level of access that a client application is asking for from the user. For instance, a scope called “email.read” might mean “can I read your emails?”, or “email.send” might mean “can I send emails on your behalf?”. Check out Auth0’s article on the &lt;a href="https://auth0.com/blog/on-the-nature-of-oauth2-scopes/"&gt;nature of OAuth scopes&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This is a fairly common mistake to make when starting out with OAuth, so I’ll forgive you for this one.&lt;/p&gt;

&lt;h3&gt;
  
  
  “I still don’t believe you! Everyone does this!”
&lt;/h3&gt;

&lt;p&gt;Well, that’s just, like, your opinion, man. But it isn’t OAuth.&lt;/p&gt;

</description>
      <category>oauth</category>
      <category>security</category>
      <category>webdev</category>
    </item>
    <item>
      <title>JWTs: Which Signing Algorithm Should I Use?</title>
      <dc:creator>Scott Brady</dc:creator>
      <pubDate>Tue, 25 Aug 2020 07:44:47 +0000</pubDate>
      <link>https://dev.to/scottbrady91/jwts-which-signing-algorithm-should-i-use-3m79</link>
      <guid>https://dev.to/scottbrady91/jwts-which-signing-algorithm-should-i-use-3m79</guid>
      <description>&lt;p&gt;JSON Web Tokens (JWTs) can be signed using many different algorithms: RS256, PS512, ES384, HS1; you can see why some developers scratch their heads when asked which one they would like to use.&lt;/p&gt;

&lt;p&gt;In my experience, many of the mainstream identity providers have historically only offered RS256 or at least defaulted to it. However, thanks to initiatives such as Open Banking, these identity providers are now expanding their support to cover more signing algorithms, which means you will need to start understanding which ones to use.&lt;/p&gt;

&lt;p&gt;I am not a cryptographer, but through my work with OpenID Connect and FIDO2, I have gained a practitioner’s understanding of the various signing algorithms and the cryptography communities’ general feelings towards each one. In this article, I’m going to arm you with some of that knowledge so that you can understand what each “alg” value means and choose the best signing algorithm available to you.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TL;DR: EdDSA &amp;gt; ECDSA or RSASSA-PSS &amp;gt; RSASSA-PKCS1-v1_5 and know what to expect.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Algorithm (alg) Values
&lt;/h2&gt;

&lt;p&gt;Before we look at each family of signature algorithms, let’s first clarify what we mean by “alg” values such as RS256. These are JSON Web Algorithms (JWA), which are part of the JavaScript Object Signing and Encryption (JOSE) family. You’ll see “alg” values in JWT headers, telling you how the JWT was signed, and in JSON Web Keys (JWK), telling you what algorithm a key is used for.&lt;/p&gt;

&lt;p&gt;As a general rule of thumb, an “alg” value, such as &lt;strong&gt;RS256&lt;/strong&gt;, can be broken down as: &lt;strong&gt;RS&lt;/strong&gt; (signature algorithm) &lt;strong&gt;256&lt;/strong&gt; (hashing algorithm).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Signature algorithm family: In this case, RS means RSASSA-PKCS1-v1_5.&lt;/li&gt;
&lt;li&gt;Hashing algorithm used by the signature algorithm. In this case, 256 means SHA-256.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most signing algorithms have variants for SHA-256, SHA-384, and SHA-512. In some cases, you can even have something like “RS1”, which uses SHA-1 🤢 and is required for FIDO2 conformance.&lt;/p&gt;

&lt;p&gt;These algorithms are typically defined in &lt;a href="https://tools.ietf.org/html/rfc7518"&gt;RFC 7518&lt;/a&gt;, but you can find a full list of supported algorithms in the &lt;a href="https://www.iana.org/assignments/jose/jose.xhtml#web-signature-encryption-algorithms"&gt;JOSE IANA registry&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Which Hashing Algorithm Should I Use?
&lt;/h2&gt;

&lt;p&gt;SHA-256, SHA-384, and SHA-512 are all variations of the same hashing algorithm family: SHA-2.&lt;/p&gt;

&lt;p&gt;As a rule of thumb, the number in an algorithm refers to the size of the hash it will generate. For example, SHA-256 will produce a 256-bit hash, while SHA-512 will produce a 512-bit hash.&lt;/p&gt;

&lt;p&gt;The level of security each one gives you is 50% of their output size, so SHA-256 will provide you with 128-bits of security, and SHA-512 will provide you with 256-bits of security. This means that an attacker will have to generate 2^128 hashes before they start finding collisions, thanks to the &lt;a href="https://en.wikipedia.org/wiki/Birthday_attack"&gt;birthday bound&lt;/a&gt;. This is why we use a minimum of 128-bit security.&lt;/p&gt;

&lt;p&gt;You’re not going to be needing anything better than SHA-256 any time soon. Just don’t use SHA-1.&lt;/p&gt;

&lt;h2&gt;
  
  
  Validation: Know your Algorithm
&lt;/h2&gt;

&lt;p&gt;Every application validating JWT signatures should know ahead of time which algorithms to expect and exactly which key to use. You can do this by assigning each public key to an algorithm (e.g. this key is for RS384, this one for ES256). When you have many keys for a single algorithm, you can use the key ID (&lt;code&gt;kid&lt;/code&gt;) in a JWT header to understand which one to use.&lt;/p&gt;

&lt;p&gt;Basically, you want to make sure the &lt;code&gt;kid&lt;/code&gt; and &lt;code&gt;alg&lt;/code&gt; values in a JWT match what you expect. If they do not match, then someone is up to no good.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "typ": "JWT",
    "kid": "123", // is this key...
    "alg": "RS256" // ...allowed to be used for this algorithm?
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Protocols such as OpenID Connect facilitate this using a discovery document and a JSON Web Key Set (JWKS) available on an endpoint protected by TLS.&lt;/p&gt;

&lt;p&gt;These days, you should not trust the “alg” value in the JWT header alone, nor should you accept JWTs with an algorithm of “none” or JWTs with a public key embedded in its header.&lt;/p&gt;

&lt;h2&gt;
  
  
  RSASSA-PKCS1-v1_5 (e.g. RS256)
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;RS256 = RSASSA-PKCS1-v1_5 using SHA-256&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;While RSAES-PKCS1-v1_5 is no longer safe for encryption, RSASSA-PKCS1-v1_5 is still suitable for digital signatures. As I mentioned earlier, in my experience, &lt;strong&gt;RS256 has historically been the default for most JWT implementations&lt;/strong&gt;, with many SaaS identity providers only offering this signature algorithm. It’s hard to find a system that can’t support JWTs signed with RS256.&lt;/p&gt;

&lt;p&gt;JWTs signed with RSASSA-PKCS1-v1_5 have a deterministic signature, meaning that the same JWT header &amp;amp; payload will always generate the same signature.&lt;/p&gt;

&lt;p&gt;RSASSA-PKCS1-v1_5 has been around for a long time, but these days, &lt;strong&gt;you should generally prefer RSASSA-PSS&lt;/strong&gt; (RSA with a probabilistic signature). That’s not to say RSASSA-PKCS1-v1_5 is broken but rather that RSASSA-PSS simply has desirable features that the other does not. In fact, RFC 8017 now considers RSASSA-PSS a requirement when using RSA for signing:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Although no attacks are known against RSASSA-PKCS1-v1_5, in the interest of increased robustness, RSASSA-PSS is REQUIRED in new applications. - &lt;a href="https://tools.ietf.org/html/rfc8017"&gt;RFC 8017&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That being said, when discussing &lt;a href="https://en.wikipedia.org/wiki/Daniel_Bleichenbacher"&gt;Bleichenbacher’s attacks&lt;/a&gt; against the RSA PKCS#1 encryption and signature standards, David Wong in Real-Word Cryptography shares an interesting statistic:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Unlike the first attack that broke the encryption algorithm completely, the second attack is an implementation attack [against signature validation]. This means that if the signature scheme is implemented correctly (according to the specification), the attack does not work.&lt;/p&gt;

&lt;p&gt;Yet, it was shown in 2019 that many open source implementations of RSA PKCS#1 v1.5 for signatures actually fell for that trap and mis-implemented the standard, which enabled different variants of Bleichenbacher’s forgery attack to work! - &lt;a href="https://www.manning.com/books/real-world-cryptography"&gt;Real-World Cryptography&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Since the attacks are against signature validation, you will have to be confident that all recipients who validate your JWTs are using a library that is not vulnerable to Bleichenbacher’s attack. That would be difficult if you are dealing with many 3rd parties.&lt;/p&gt;

&lt;p&gt;The work around Open Banking, such as OpenID’s Financial-grade API (FAPI), does not allow the use of RSASSA-PKCS1-v1_5. For my regular readers, this was the only algorithm available in IdentityServer up until IdentityServer4 version 3.&lt;/p&gt;

&lt;h3&gt;
  
  
  Further Reading
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Learn how to &lt;a href="https://www.scottbrady91.com/OpenSSL/Creating-RSA-Keys-using-OpenSSL"&gt;generate RSA keys&lt;/a&gt; for JWT signing using OpenSSL&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  RSASSA-PSS (e.g. PS256)
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;PS256 = RSASSA-PSS using SHA-256 with MGF1 with SHA-256&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;RSASSA-PSS is the probabilistic version of RSA, where the same JWT header and payload will generate a different signature each time. Unlike other algorithms, this is probabilistic in a good way; while a random value may be used during signature generation, it is not critical to security. In general, it’s a lot simpler to implement and therefore harder to get wrong.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you want to use an RSA key, then it’s recommended that you use RSASSA-PSS&lt;/strong&gt; over RSASSA-PKCS1-v1_5, but luckily an RSA key can be used for either signature scheme. Signature length is also identical between the two.&lt;/p&gt;

&lt;p&gt;The UK’s Open Banking initially mandated the use of PS256, but later opened it up to ES256.&lt;/p&gt;

&lt;h3&gt;
  
  
  Further Reading
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Learn more about &lt;a href="https://www.scottbrady91.com/C-Sharp/JWT-Signing-using-RSASSA-PSS-in-dotnet-Core"&gt;RSASSA-PSS and how to use it in .NET Core&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Learn how to &lt;a href="https://www.scottbrady91.com/OpenSSL/Creating-RSA-Keys-using-OpenSSL"&gt;generate RSA keys&lt;/a&gt; for JWT signing using OpenSSL&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  ECDSA (e.g. ES256)
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;ES256 = ECDSA using P-256 and SHA-256&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In the case of Elliptical Curve Digital Signing Algorithms (ECDSA), the number in ES256 that refers to the hashing algorithm also relates to the curve. ES256 uses P-256 (secp256r1, aka prime256v1), ES384 uses P-384 (secp384r1), and, the odd one out, ES512 uses P-521 (secp521r1). Yes, 521. Yes, &lt;a href="https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/blob/master/src/Microsoft.IdentityModel.Tokens/JsonWebKeyECTypes.cs#L40"&gt;even Microsoft&lt;/a&gt; has typoed this.&lt;/p&gt;

&lt;p&gt;Elliptical Curve Cryptography (ECC) is much harder to crack than RSA (or maybe we are just really good at breaking RSA). As a result, &lt;strong&gt;ECDSA can use much shorter keys than RSA along with much shorter signatures&lt;/strong&gt;. A short Elliptical Curve (EC) key of around 256 bits provides the same security as a 3072 bit RSA key.&lt;/p&gt;

&lt;p&gt;You will often see ECDSA listed as faster than its equivalent in RSA, but this is only really true for signature generation; signature validation is still typically faster with RSA. With JWTs, you’re most likely going to be signing once and verifying many times.&lt;/p&gt;

&lt;p&gt;JWTs signed with ECDSA have a probabilistic signature, meaning that the same JWT header &amp;amp; payload will always generate a different signature. But unfortunately, ECDSA is probabilistic in a bad way, where random generation is vital to the security of the signature.&lt;/p&gt;

&lt;p&gt;ECDSA uses a random nonce (no more than once) that is generated per signature. Failure to only ever use a nonce value once makes the private key easily recoverable, and this has been seen in the wild with both &lt;a href="https://medium.com/asecuritysite-when-bob-met-alice/not-playing-randomly-the-sony-ps3-and-bitcoin-crypto-hacks-c1fe92bea9bc"&gt;Sony’s Playstation 3 and Bitcoin&lt;/a&gt;. With the Playstation 3, the private key was recovered due to a static nonce, and with Bitcoin, Android users were affected due to a bug in Java’s SecureRandom class on Android. &lt;strong&gt;If random values are required for the security of a probabilistic signature, then you should prefer a deterministic signature that does not&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Whereas RSASSA-PKCS1-v1_5 has issues with signature validation, ECDSA has issues with signature generation, which is much easier to deal with when you are the token issuer.&lt;/p&gt;

&lt;p&gt;ECDSA is gaining popularity but seems to generally be frowned upon by cryptographers due to how elliptical curve cryptography was implemented, with concerns around implementation difficulty due to the use of random values. It has a better reputation than RSA, but &lt;strong&gt;cryptographers are still advocating the migration to EdDSA&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The curves JOSE initially used where defined by NIST. If you are concerned about using curves defined by NIST but want to use ECDSA, a popular alternative is to use a Koblitz curve, such as secp256k1 (as opposed to secp256r1). Kobiltz curves are a few bits weaker, but if you have concerns that the unexplained random numbers used in the NIST curves indicate another NSA backdoor, then Kobiltz curves offer an increasingly popular alternative. You can find usages on these curves in Bitcoin, Ethereum, and FIDO2. However, you should be using EdDSA if you want to use a non-NIST curve. In JOSE, algorithms using Kobiltz end with a K, e.g. ES256K.&lt;/p&gt;

&lt;h2&gt;
  
  
  Further Reading
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Learn &lt;a href="https://www.scottbrady91.com/C-Sharp/JWT-Signing-using-ECDSA-in-dotnet-Core"&gt;how to use ECDSA in .NET Core&lt;/a&gt; and how to &lt;a href="https://www.scottbrady91.com/Identity-Server/Using-ECDSA-in-IdentityServer4"&gt;sign tokens with ECDSA in IdentityServer4&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Learn how to &lt;a href="https://www.scottbrady91.com/OpenSSL/Creating-RSA-Keys-using-OpenSSL"&gt;generate EC keys&lt;/a&gt; for JWT signing using OpenSSL&lt;/li&gt;
&lt;li&gt;Use custom JWT signing algorithms in .NET Core, &lt;a href="https://www.scottbrady91.com/C-Sharp/Supporting-Custom-JWT-Signing-Algorithms-in-dotnet-Core"&gt;with examples using Kobiltz curves&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  EdDSA
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;EdDSA = an EdDSA signature algorithm was used&lt;/em&gt; 🤷‍♂️&lt;/p&gt;

&lt;p&gt;EdDSA bucks the trend of the previous algorithms and uses a single &lt;code&gt;alg&lt;/code&gt; value. Instead, it relies upon the curve (&lt;code&gt;crv&lt;/code&gt;) defined in a pre-agreed key.&lt;/p&gt;

&lt;p&gt;For example, a JWK containing an EdDSA public key would look like the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "kty": "OKP",
  "alg": "EdDSA",
  "crv": "Ed25519",
  "x": "60mR98SQlHUSeLeIu7TeJBTLRG10qlcDLU4AJjQdqMQ"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This forces the modern behavior of using the curve assigned to the key, as opposed to from the JWT, and eliminates various alg related attacks.&lt;/p&gt;

&lt;p&gt;EdDSA is a form of elliptical curve cryptography that takes advantage of twisted Edwards curves. It is a variant of Schnorr’s signature system (rather than DSA). &lt;strong&gt;EdDSA is fast at both signing and validation, has a short signature, and side-steps whole classes of security vulnerabilities&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;RFC 8037 defines JOSE support for the following EdDSA variants:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Ed25519&lt;/strong&gt;: a 255-bit curve Curve25519 (32-byte private key, 32-byte public key, 64-byte signature). Signing uses SHA-512. Provides 128-bit security&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ed448&lt;/strong&gt;: a 448-bit curve Curve448-Goldilocks (57-byte private key, 57-byte public key, 114-byte signature). Signing uses SHAKE256. Provides 224-bit security
JWTs signed with EdDSA have a deterministic signature, meaning that the same JWT header &amp;amp; payload will always generate the same signature. This is deterministic in a good way, addressing the concern of relying on random nonce values to protect the private key. EdDSA only uses random values during private key creation. This is the algorithm that &lt;a href="https://www.scottbrady91.com/JOSE/Alternatives-to-JWTs"&gt;critics of JOSE &amp;amp; JWTs recommend&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Support for EdDSA in JWT libraries is a little patchy, but &lt;strong&gt;expect to see more of EdDSA soon&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Further Reading
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Learn more about &lt;a href="https://www.scottbrady91.com/C-Sharp/EdDSA-for-JWT-Signing-in-dotnet-Core"&gt;EdDSA and how to use it in .NET Core&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/scottbrady91/IdentityModel"&gt;Start using EdDSA for JWT signing&lt;/a&gt; in .NET Core using ScottBrady.IdentityModel&lt;/li&gt;
&lt;li&gt;Read more about the design benefits of EdDSA at &lt;a href="https://ed25519.cr.yp.to/"&gt;cr.yp.to&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  HMAC (e.g. HS256)
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;HS256 = HMAC using SHA-256&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Up until now, we’ve been talking about asymmetric cryptography, where only the token issuer has the private key to create the signature, and everyone else has the corresponding public key that can be used to validate the signature. For example, the identity provider has the private key and relying parties use a public key.&lt;/p&gt;

&lt;p&gt;In the &lt;em&gt;rare&lt;/em&gt; event that you will be the only person who issues and validates tokens, then you could consider using symmetric cryptography with something like HS256. &lt;strong&gt;This uses the same key to both create and validate a signature&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In my opinion, if you find yourself in this position, then I don’t think JWTs are the right solution for you. If the same entity is both reading and writing, then what is the requirement for round-tripping structured, plaintext data in a JWT? I would recommend storing the data in a database and passsing around a reference or to use something like a Branca token or JSON Web Encryption (JWE) to ensure only you can read the data.&lt;/p&gt;

&lt;p&gt;Generally, using HMAC for JWT signing is seen as something of an anti-pattern.&lt;/p&gt;

&lt;h3&gt;
  
  
  Further Reading
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Learn more about &lt;a href="https://www.scottbrady91.com/C-Sharp/JSON-Web-Encryption-JWE-in-dotnet-Core"&gt;JWE and how to use them in .NET Core&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Learn &lt;a href="https://www.scottbrady91.com/C-Sharp/Replacing-JWTs-with-Branca-and-PASETO-in-dotnet-Core"&gt;how to use Branca tokens&lt;/a&gt; with ScottBrady.IdentityModel&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  None
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;none = base64 encrypted&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Sorry, I couldn't resist. &lt;strong&gt;Please don’t use this.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Recommendations
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Use EdDSA where possible and use ECDSA when it is not&lt;/strong&gt;. If you are forced to use RSA, prefer RSASSA-PSS over RSASSA-PKCS1-v1_5.&lt;/p&gt;

&lt;p&gt;I don’t think it’s a controversial statement to say that RSA is slowly on its way out. At the moment, offering ECDSA is a good alternative, but ideally, you’ll be wanting to move to EdDSA where possible.&lt;/p&gt;

&lt;p&gt;But, no matter which algorithm you use, make sure you know ahead of time which algorithm to expect and which key to use for validation.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;A huge thank you to &lt;a href="https://neilmadden.blog/"&gt;Neil Madden&lt;/a&gt; for the technical review of this blog post.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>jwt</category>
      <category>security</category>
      <category>webdev</category>
      <category>cryptography</category>
    </item>
    <item>
      <title>Creating Elliptical Curve Keys using OpenSSL</title>
      <dc:creator>Scott Brady</dc:creator>
      <pubDate>Mon, 20 Jul 2020 17:22:48 +0000</pubDate>
      <link>https://dev.to/scottbrady91/creating-elliptical-curve-keys-using-openssl-28h1</link>
      <guid>https://dev.to/scottbrady91/creating-elliptical-curve-keys-using-openssl-28h1</guid>
      <description>&lt;p&gt;Recently, I have been using OpenSSL to &lt;strong&gt;generate private keys and X509 certificates for Elliptical Curve Cryptography&lt;/strong&gt; (ECC) and then using them in ASP.NET Core for token signing.&lt;/p&gt;

&lt;p&gt;In this article, I’m going to show you how to use OpenSSL to generate private and public keys on the curve of your choice.&lt;/p&gt;

&lt;h2&gt;
  
  
  tl;dr - OpenSSL ECDSA Cheat Sheet
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# find your curve
openssl ecparam -list_curves

# generate a private key for a curve
openssl ecparam -name prime256v1 -genkey -noout -out private-key.pem

# generate corresponding public key
openssl ec -in private-key.pem -pubout -out public-key.pem

# optional: create a self-signed certificate
openssl req -new -x509 -key private-key.pem -out cert.pem -days 360

# optional: convert pem to pfx
cat private-key.pem cert.pem &amp;gt; cert-with-private-key
openssl pkcs12 -export -inkey private-key.pem -in cert-with-private-key -out cert.pfx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Generating an Elliptical Curve Private Key Using OpenSSL
&lt;/h2&gt;

&lt;p&gt;To start, you will need to choose the curve you will be working with. You can use the following command to see a list of supported curve names and descriptions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;openssl ecparam -list_curves
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, I am using prime256v1 (secp256r1), which is suitable for JWT signing; this is the curve used for JOSE’s ES256.&lt;/p&gt;

&lt;p&gt;You can now generate a private key:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;openssl ecparam -name prime256v1 -genkey -noout -out private-key.pem
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This should give you a PEM file containing your EC private key, which looks something like the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;----------BEGIN EC PRIVATE KEY-----
MHcCAQEEIKEubpBiHkZQYlORbCy8gGTz8tzrWsjBJA6GfFCrQ98coAoGCCqGSM49
AwEHoUQDQgAEOr6rMmRRNKuZuwws/hWwFTM6ECEEaJGGARCJUO4UfoURl8b4JThG
t8VDFKeR2i+ZxE+xh/wTBaJ/zvtSqZiNnQ==
----------END EC PRIVATE KEY-----
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Creating an EC Public Key from a Private Key Using OpenSSL
&lt;/h2&gt;

&lt;p&gt;Now that you have your private key, you can use it to generate another PEM, containing only your public key.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;openssl ec -in private-key.pem -pubout -out public-key.pem
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This should give you another PEM file, containing the public key:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;----------BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEOr6rMmRRNKuZuwws/hWwFTM6ECEE
aJGGARCJUO4UfoURl8b4JThGt8VDFKeR2i+ZxE+xh/wTBaJ/zvtSqZiNnQ==
----------END PUBLIC KEY-----
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Creating an EC Self-Signed Certificate Using OpenSSL
&lt;/h2&gt;

&lt;p&gt;Now that you have a private key, you could use it to generate a self-signed certificate. This is not required, but it allows you to use the key for server/client authentication, or gain X509 specific functionality in technologies such as JWTs and SAML.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;openssl req -new -x509 -key private-key.pem -out cert.pem -days 360
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will again generate another PEM file, this time containing the certificate created by your private key:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;----------BEGIN CERTIFICATE-----
MIIB4DCCAYWgAwIBAgIUH53ssiPt4JEGx+VJyntCpHL+TdAwCgYIKoZIzj0EAwIw
RTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGElu
dGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yMDA3MTgxMTE4NDNaFw0yMTA3MTMx
MTE4NDNaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYD
VQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwWTATBgcqhkjOPQIBBggqhkjO
PQMBBwNCAAQ6vqsyZFE0q5m7DCz+FbAVMzoQIQRokYYBEIlQ7hR+hRGXxvglOEa3
xUMUp5HaL5nET7GH/BMFon/O+1KpmI2do1MwUTAdBgNVHQ4EFgQU9yjFBqAZOMv+
cD6a3KHTWuYrcFEwHwYDVR0jBBgwFoAU9yjFBqAZOMv+cD6a3KHTWuYrcFEwDwYD
VR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAgNJADBGAiEAwCpA5Nx083qqUqU6LUd0
vzZLK4etuInxNvXohXH5LiACIQDSI63J4DiN3dq2sPPLw5iQi9MMefcV1iAySbKT
B9BaAw==
----------END CERTIFICATE-----
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You could leave things there, but if you are working on Windows, you may prefer a PFX file that contains both the certificate and the private key for you to export and use.&lt;/p&gt;

&lt;p&gt;You can do this by first concatenating your private key and certificate into a single file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cat private-key.pem cert.pem &amp;gt; cert-with-private-key
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And then using OpenSSL to create a PFX file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;openssl pkcs12 -export -inkey private-key.pem -in cert-with-private-key -out cert.pfx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;OpenSSL will ask you to create a password for the PFX file. Feel free to leave this blank.&lt;/p&gt;

&lt;p&gt;This should leave you with a certificate that Windows both install and export the private key from.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--r-uwZKou--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/n1qnni18oquwmn27zu7a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--r-uwZKou--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/n1qnni18oquwmn27zu7a.png" alt="A certificate, opened in Windows 10, showing that a private key corresponding to this certificate is present."&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>openssl</category>
      <category>ecdsa</category>
      <category>cryptography</category>
      <category>security</category>
    </item>
  </channel>
</rss>
