It took $70 and 24 hours for Ryan Castellucci to gain access to 200 MW of capacity.

512-bit RSA key in home energy system gives control of “virtual power plant”
Enlarge

When Ryan Castellucci recently acquired solar panels and a battery storage system for their home just outside of London, they were drawn to the ability to use an open source dashboard to monitor and control the flow of electricity being generated. Instead, they gained much, much more—some 200 megawatts of programmable capacity to charge or discharge to the grid at will. That’s enough energy to power roughly 40,000 homes.

Castellucci, whose pronouns are they/them, acquired this remarkable control after gaining access to the administrative account for GivEnergy, the UK-based energy management provider who supplied the systems. In addition to the control over an estimated 60,000 installed systems, the admin account—which amounts to root control of the company’s cloud-connected products—also made it possible for them to enumerate names, email addresses, usernames, phone numbers, and addresses of all other GivEnergy customers (something the researcher didn’t actually do).

“My plan is to set up Home Assistant and integrate it with that, but in the meantime, I decided to let it talk to the cloud,” Castellucci wrote Thursday, referring to the recently installed gear. “I set up some scheduled charging, then started experimenting with the API. The next evening, I had control over a virtual power plant comprised of tens of thousands of grid connected batteries.”

Still broken after all these years

The cause of the authentication bypass Castellucci discovered was a programming interface that was protected by an RSA cryptographic key of just 512 bits. The key signs authentication tokens and is the rough equivalent of a master-key. The bit sizes allowed Castellucci to factor the private key underpinning the entire API. The factoring required $70 in cloud computing costs and less than 24 hours. GivEnergy introduced a fix within 24 hours of Castellucci privately disclosing the weakness.

Ars Video

How Scientists Respond to Science Deniers

Further Reading

Breaking 512-bit RSA with Amazon EC2 is a cinch. So why all the weak keys?

The first publicly known instance of 512-bit RSA being factored came in 1999 by an international team of more than a dozen researchers. The feat took a supercomputer and hundreds of other computers seven months to carry out. By 2009 hobbyists spent about three weeks to factor 13 512-bit keys protecting firmware in Texas Instruments calculators from being copied. In 2015, researchers demonstrated factoring as a service, a method that used Amazon cloud computing, cost $75, and took about four hours. As processing power has increased, the resources required to factor keys has become ever less.

It’s tempting to fault GivEnergy engineers for pinning the security of its infrastructure on a key that’s trivial to break. Castellucci, however, said the responsibility is better assigned to the makers of code libraries developers rely on to implement complex cryptographic processes.

“Expecting developers to know that 512 bit RSA is insecure clearly doesn’t work,” the security researcher wrote. “They’re not cryptographers. This is not their job. The failure wasn’t that someone used 512 bit RSA. It was that a library they were relying on let them.”

Castellucci noted that OpenSSL, the most widely used cryptographic code library, still offers the option of using 512-bit keys. So does the Go crypto library. Coincidentally, the Python cryptography library removed the option only a few weeks ago (the commit for the change was made in January).

In an email, a GivEnergy representative reinforced Castellucci’s assessment, writing:

In this case, the problematic encryption approach was picked up via a 3rd party library many years ago, when we were a tiny startup company with only 2, fairly junior software developers & limited experience. Their assumption at the time was that because this encryption was available within the library, it was safe to use. This approach was passed through the intervening years and this part of the codebase was not changed significantly since implementation (so hadn’t passed through the review of the more experienced team we now have in place).

A key factor

RSA encryption relies on extremely large numbers that are the product of two prime numbers. The large number, known as a modulus, is typically denoted as ‘n’ while the primes are denoted as ‘p’ and ‘q.’ While it’s easy to multiply the two prime numbers, it’s nearly impossible for someone with only the modulus of a key of sufficient length to identify its two underlying prime numbers, a process known as factorizing. The difficulty of solving this problem allows for the creation of two keys. One is a public key anyone can have and the other is a private key that must be kept absolutely secret. Factorizing a key pair completely breaks their security because it reveals the private portion.

The difficulty of solving this problem is directly proportional to the number of possible primes that must be tested. The more possibilities the harder it is to find the right pair. This entropy, in turn, is proportional to the bit length of the modulus. In 2019, a team of researchers factored a 795-bit RSA key, making it the biggest key size to be broken at the time. A year later, researchers factorized an 829-bit RSA key. To date, there are no confirmed cases of 1024-bit RSA being factorized, but that doesn’t mean it can’t be done.

“The only barrier for [factorizing 1024-bit RSA] in public is some engineering effort and funding, and finding a large organization willing to put up enough computing power,” Nadia Heninger, a University of California at San Diego professor specializing in cryptography, wrote in an email. “It could have been done years ago if people wanted to—there’s no technical barrier, and multiple large companies certainly have the computing resources.”

Anticipating the inevitable fall of 1024-bit RSA, the US National Institute of Standards and Technology stopped allowing its use in 2013 and will stop allowing the use of 2048-bit RSA in 2031. Microsoft earlier this year announced the deprecation of 1024-bit RSA in Windows.

Castillucci’s task was made more difficult because they didn’t have access to the public key securing the admin account. Instead they had only a JWT—short for a JSON Web Token—that was signed by the key. Castellucci explained how they overcame the limitation:

RSA needs three values to work, the modulus n, the private exponent d, and the public exponent e. An RSA signature is computed as s = md mod n — message m is raised to the power of d modulo n. It’s validated by checking that se mod n ≡ m. With the prime factors of n, it’s trivial to calculate d, and for a 512 bit key finding the prime factors is doable, but I didn’t have n or e. By convention, e is nearly always 65537, but I had no idea what n was. I do, however, know algebra.

Subtracting m from both sides of the signature verification equation gives se mod n − m ≡ 0. Since modular subtraction is associative, that also means that se − m mod n ≡ 0. The modulo operation finds the remainder, so se − m is an integer multiple of n. This is not useful on its own, but it means that with another message and signature, I’d have two different integer multiples of n. Running those through a GCD algorithm would give me n × x where x is a small integer, easily factored out by trial division.

This Isn’t Textbook RSA

The math above only covers “Textbook RSA” operating on raw numbers, which has a number of problems in practice. It can only operate on numbers smaller than the key’s modulus. The numbers also can’t be too small, otherwise various attacks are possible. To address this, the message is hashed and padded using PKCS #1 v1.5 encoding before being signed. Not wanting to deal with the encoding, I went looking for a pre-existing tool. After a few false starts, I found JWT-Key-Recovery, which quickly provided the modulus.

Cracking the Key

The modulus is generated by picking large prime numbers, usually denoted p and q, and multiplying them together. If you want more detail, please see my previous post, Artisanal RSA. The most efficient known algorithm for factoring the modulus back into primes is called general number field sieve (GNFS). This wasn’t my first time cracking an RSA key, but it’d been a while, so I found some instructions. I started cado-nfs on my workstation and let it run overnight. By the time I got done with work the next day, I was feeling impatient and rented a few hundred CPU cores to make it go faster. A few hours and a $70 compute bill later, I had the two prime numbers I needed.

Once in possession of the two primes, the researcher used a custom tool to generate the private key and then signed the JWT provided with a demo account they were using. With a few additional steps, Castellucci had transformed the token to give the same access admins inside GivEnergy had.

Based on the sequential numbering of each account, Castellucci estimated that the account had control of about 60,000 installed systems. Assuming each system can charge or discharge 3 to 4 kW per inverter, that equates to roughly 200 MW of electricity.

Castellucci praised GivEnergy for taking their report seriously and fixing it less than a day after receiving it. The researcher confirmed that factorizing the API key was no longer possible. GivEnergy disclosed its previous use of the weak key here. An analysis of system logs indicated the weakness had never been exploited maliciously, the company said.

In an interview, Castellucci returned to the problem of outdated code libraries that still haven’t removed support for weak keys and noted the potentially catastrophic harm that can result years later.

“The GivEnergy issue I found was someone stepping on an old land mine,” they said. “These ones just take a couple years before they actually blow your leg off.”

LEAVE A REPLY

Please enter your comment!
Please enter your name here