I previously wrote an article on how to use Proof-Key for Code Exchange (PKCE) in a server-side ASP.NET Core application. In the IdentityServer world authorization code with PKCE now replaces OpenID Connect's (OIDC) hybrid flow as our most secure authorization method; however, not all client libraries or even OpenID Providers support PKCE yet. An alternative approach that gives a comparatively high level of assurance is to use the OIDC hybrid flow in combination with encrypted identity tokens via JSON Web Encryption (JWE).
Using the hybrid flow with encrypted identity tokens allows us to validate the authorization response (via identity token validation), ensure that the authorization code was intended for us (via c_hash validation), and prevent PII passing via the browser (thanks to JWE).
To help a 10% project at work, the Rock Solid Knowledge IdentityServer team has been creating a basic OpenID Connect library for a Flutter application. After poking around in Dart over the weekend, I found that Dart did not have a straightforward way to create a cryptographically random string suitable for OAuth/OpenID Connect values such as state, nonce, or PKCE’s code challenge. So, in this article, I’m going to share a straightforward way to generate one.
Dart’s Random Number Generator
Luckily, Dart does have a cryptographically secure random number generator that we can use, found in the dart:math library.
I’ve recently started the cryptopals crypto challenges, and, frankly, even the basics are kicking my ass. However, I seem to be enjoying them, and I’m finally starting to understand some of the Computer Science topics I really should have listened to at University. If you are like me and prefer learning by getting your hands dirty and hacking some code together, then I highly recommend working through some of these challenges.
If you have not heard about cryptopals before, then I'll leave it to the creators to explain:
“We've built a collection of 48 exercises that demonstrate attacks on real-world crypto.
This is a different way to learn about crypto than taking a class or reading a book. We give you problems to solve. They're derived from weaknesses in real-world systems and modern cryptographic constructions. We give you enough info to learn about the underlying crypto concepts yourself. When you're finished, you'll not only have learned a good deal about how cryptosystems are built, but you'll also understand how they're attacked.”
We’ve all used Convert.ToBase64String() but what is it actually happening under the covers? Sure, it’s taking a value and representing it using only characters from a range of 64 characters, but how exactly does it do that? Up until now, I probably couldn’t have told you.
My favorite example for understanding how Base64 encoding works is actually from Wikipedia...
The next few challenges cover implementing and then breaking the Caesar and Vigenère ciphers. These ciphers usually serve as the introduction to most cryptography books, as a history lesson of what we used to use and how easy they are to break. However, with cryptopals, we take this academic knowledge and turn it into practice.
This article will show you how to configure a Kotlin Ktor application to get access tokens from IdentityServer4 using OAuth 2.0. These tokens can then be used to access an API on behalf of a user. We’ll be using JWTs as our access tokens. To find out how to authorize access to a Ktor API using JWTs, check out my past article “JSON Web Token Verification in Ktor using Kotlin and Java-JWT”.
Ktor OAuth Support
Currently, Ktor only supports OAuth which means our Ktor application can receive access tokens to talk to an API on behalf of the user, but it cannot find out who the user is. If we wanted to find out who the user is and to receive identity tokens, we would need OpenID Connect, which is currently unsupported...
Proof Key for Code Exchange (PKCE) was initially designed for native/mobile client applications when using OAuth; however, as a happy accident, it’s also handy for all other kinds of applications. Because of this, new specifications and BCP documents are starting to encourage the use of PKCE across the board.
PKCE allows us to ensure that the client application swapping an authorization code for tokens, is the same application that initially requested the authorization code. It protects us from bad actors from stealing authorization codes and using them.
In this article, we’re going to see how we can add PKCE support to an existing ASP.NET Core OpenID Connect client application (with some IdentityServer4 config thrown in for good measure).
Confused how to properly authenticate access an API when using a browser-based application? Then use the below cheat sheet to choose the right approach for your needs.
I have an application running within the context of the browser (e.g. a React or Angular Single Page Application (SPA)) that wants to access an API on behalf of a user. This authenticated API call will be made directly from the user’s browser, and only our application should be able to call it on behalf of our authenticated user (i.e. we’re not vulnerable to Cross-Site Request Forgery (CSRF/XSRF).
A signed JSON Web Token (JWT) is one of the most useful and common constructs you’ll see floating around modern security systems. These tokens give us a simple, secure structure in which to transfer data and verify that it has not been tampered with. However, what about when we need to send sensitive data within a JWT?
To solve this issue, we have JSON Web Encryption (JWE), enabling us to encrypt a token so that only the intended recipient can read it.
In this article, we’re going to look at how we can protect sensitive data within our JWTs in .NET Core, using JWEs and the various token libraries available to us.
We’re going to use JWE Compact Serialization (as opposed to JWE JSON Serialization), which looks something like the following...