The Elliptic Curve Digital Signature Algorithm Flaw

JANBAR MOHAMMED
System Weakness
Published in
5 min readFeb 21, 2023

--

A simple introduction to DSA

As you know the digital signature is used to verify :

  • The document is created by the author with public key
  • The message or document is not tampared

This Digital signature can be generated by any cryptographic hash function like SHA256.

We can say that Digital signatures are an asymmetrically encrypted hash of a digital message (data), It is a value that can provide a guarantee of authenticity, non-repudiation and integrity.

The most important thing to note is that the author or client sends both public key and the signature key with the message.

Here is a small diagram that summarizes the process.

A message digest is a cryptographic hash function containing a string of digits generated in one-way.

The JAVA language like all other languages offers classes for generating key pair, signing and verifying signatures, here we will focus on the standard libraries provided with JDK precisely the implementations of the ECDSA signature verification algorithm, between JDK 15 and 18.

What is ECDSA ?

ECDSA is the elliptic curve analogue of the Digital Signature Algorithm (DSA), and is widely used in a variety of authentication processes, such as SSL/TLS handshakes, JSON Web Tokens, SAML assertions, and OAuth2/OpenID Connect.

The ECDSA is based on an elliptical mathematical function, without going too much into the details of the mathematical function, the result being two numbers of a fixed size called R and S. for an encryption key using the curve P-1363, R and S each have the size 64 while for an encryption key following the curve P-384, the size of R and S is 46.

How Hackers Can Exploit Weak ECDSA Signatures?

The flaw is very simple, our friends the Oracle developers, and our friends at OpenJDK forgot to check that the two properties R and S are not 0, So

the fault is that the verification algorithm accepts (r,s) = (0,0 ) as a valid ECDSA signature on any message :)

The CVE assigned to this flaw is the following CVE-2022–21449- and it is known as Psychic Signatures Vulnerability In Java.

I have coded a small demo in JAVA for you :

This class at the bottom is a service layer class, it is managed by spring, and simply allows you to:

  1. Generate the private and public Key and the signature from a message.
  2. Validate the digital signature using the public key and the signature key.

Here is a small integration test to verify the nominal scenarios as well as an exploitation scenario using an empty signing key. So now you can see that our backend accepts blank signature as valid signature for arbitrary message and public key.

I will show you below an HTTP request sent to my JAVA backend, this request uses a JWT token generated with the “ES256” algorithm.

I’m not going to explain JWT to you in another article if you want, but architects and developers know that a JWT token is composed of 3 main elements,

  1. A header, used to describe the token. It is a JSON object.
  2. A payload that represents the information embedded in the token.
  3. A digital signature (used to validate the token from 1+2+public key+digital signature key).

Here is an example of a function to validate the JWT token (I often see developers using almost the same code, even in the most famous software).

Don't forget, the backend of this example uses JDK 1.8 (the vulnerable version) and the token is signed with the EC256 key.

If you use this kind of implementation (this is the case for many people) and if you use jdk between 15 and 18 then authentication to your application can be easily bypassed with a signature key like this “MAYCAQACAQA =” this signature is to be put in the 3rd part of the JWT token.

As we already explained specifying an ECDSA signature with r=s=0 encoded in DER, MAYCAQACAQA=, allows us to bypass the JWT verification check :) :) :)

What is this value MAYCAQACAQA ???

We will use an ASN 1 decoder to understand what this character string is encoded in base64, personally when I don’t have time i use this site decoder :

When we decode this value, we find that it simply represents 0x0 and 0x0 for the two factors R and S encoded in DE format R.

This request will hack your system Pay attention, go quickly to the remediation/mitigation part of this article :)

Mitigation

The flaw CVE-2022–21449 impacts all application that use ECDSA signatures

  1. OpenJDK versions 15, 17, 18
  2. Oracle GraalVM Enterprise Edition: 20.3.5, 21.3.1, 22.0.0.2
  3. Oracle Java SE: 7u331, 8u321, 11.0.14, 17.0.2, 18

You should know that

  1. All JAVA version earlier than 15 are not vulnerable to this flaw.
  2. You must upgrade any JAVA application running on Java 15, 16, 17, or 18 version to v18.0.1 and 17.0.3 or ++.
  3. If you use Oracle GraalVM Enterprise Edition, then you should upgrade to v22.1
  4. Call your partners and ensure that all hird-party applications have patched and fixed the CVE-2022–21449 vulnerability.
  5. Do code reviews to identify the algorithms you use, MAC algorithms like HMAC are considerably more difficult to hack than signature schemes. If you must use a signature, consider using a modern algorithm that avoids this kind of banal problem.

--

--