TECHNICAL ANALYSIS OF JAVA PSYCHIC SIGNATURES CVE-2022–21449

TECHNICAL ANALYSIS OF JAVA PSYCHIC SIGNATURES CVE-2022–21449

To create a secure digital communication, we must encrypt data so that only authorized individuals can decrypt and read it, and additionally sign the data to verify the sender's identity. When you encrypt a message, you use the recipient's public key while they read it with their private key. When signing, you sign the communication with your private key, and they validate it with your public key.

Elliptic Curve Digital Signature Algorithm?(ECDSA) is a data signing algorithm whose implementation had a vulnerability, CVE-2022–21449, in Java versions 15, 16, 17, and 18 before the April 2022 Critical Patch Update (CPU).

The ECDSA signing algorithm (RFC 6979) accepts a message and the sender's private key as input and returns a signature consisting of two integers,?r, and?s. The integer?r?represents a random point on the Elliptic Curve, while the integer?s?represents a calculated signature proof. On the receiver's side, the algorithm for verifying an ECDSA signature takes as input the signed message (hash), the signature(r, s), and the public key, which corresponds to the signer's private key. The verification test produces a boolean value indicating if the signature is valid or invalid.

No alt text provided for this image

To verify an ECDSA signature, we must compare?r?by?r?multiplied by a value obtained from?s, the signer's public key, and the message's hash (r = r * [a value derived from s]). If both sides of the equation are equal, the signature is valid; otherwise, it is rejected as invalid. The first check in the ECDSA verification algorithm validates that r and s are both equal to or greater than one, which the affected Java versions do not. If r and s are both zero, you'll be testing that 0 = 0, which is always true, and always a valid signature - a psychic signature.

Here's an interactive jshell session that demonstrates the vulnerable implementation accepting a fully blank signature as legitimate for any message and public key:


% jshell
|? Welcome to JShell -- Version 11.0.15
|? For an introduction type: /help intro


jshell> import java.security.*


jshell> var keys = KeyPairGenerator.getInstance("EC").generateKeyPair()
keys ==> java.security.KeyPair@cd2dae5


jshell> var blankSignature = new byte[64]
blankSignature ==> byte[64] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ... , 0, 0, 0, 0, 0, 0, 0, 0 }


jshell> var sig = Signature.getInstance("SHA256WithECDSAInP1363Format")
sig ==> Signature object: SHA256WithECDSAInP1363Format<not initialized>


jshell> sig.initVerify(keys.getPublic())


jshell> sig.update("Hello, World".getBytes())


jshell> sig.verify(blankSignature)
$7 ==> true


jshell> /exit
|? Goodbye
%        

If you use one of the vulnerable versions, an attacker can easily counterfeit SSL certificates and handshakes (enabling eavesdropping and alteration of communications), signed JWTs, SAML assertions, or OIDC id tokens, and even WebAuthn authentication messages.

If you are using Java 15 or later, please update to the current release to resolve this issue.

要查看或添加评论,请登录

Kenneth Kaane的更多文章

社区洞察

其他会员也浏览了