public final class EncryptionUtils
extends java.lang.Object
| Modifier and Type | Field and Description |
|---|---|
static java.lang.String |
ALGORITHM_TYPE |
| Modifier and Type | Method and Description |
|---|---|
static javax.crypto.Cipher |
createCipher(boolean gcm,
boolean encrypt,
javax.crypto.SecretKey key) |
static java.lang.String |
createHandshakeJwt(java.security.KeyPair serverKeyPair,
byte[] token)
Create handshake JWS used in the
ServerToClientHandshakePacket
which completes the encryption handshake. |
static java.lang.String |
createHandshakeJwt(java.security.KeyPair serverKeyPair,
byte[] token,
java.lang.String signedToken)
Create handshake JWS used in the
ServerToClientHandshakePacket
which completes the encryption handshake. |
static java.security.KeyPair |
createKeyPair()
Create EC key pair to be used for handshake and encryption
|
static java.lang.String |
extractServerTokenFromEduTokenChain(java.lang.String eduTokenChain)
Extract the inner server token from an Education Edition login JWT (EduTokenChain).
|
static byte[] |
generateRandomToken()
Generate 16 bytes of random data for the handshake token using a
SecureRandom |
static java.security.PublicKey |
getEducationPublicKey()
Microsoft's public key used to verify Education Edition server tokens.
|
static java.security.interfaces.ECPublicKey |
getMojangPublicKey()
Mojang's public key used to verify the JWT during login.
|
static javax.crypto.SecretKey |
getSecretKey(java.security.PrivateKey localPrivateKey,
java.security.PublicKey remotePublicKey,
byte[] token)
Generate the secret key used to encrypt the connection
|
static java.security.interfaces.ECPublicKey |
parseKey(java.lang.String b64)
Generate EC public key from base 64 encoded string
|
static ChainValidationResult |
validateChain(java.util.List<java.lang.String> chain) |
static EducationTokenValidationResult |
validateEducationPayload(java.lang.String eduTokenChain)
Validate the Education Edition login JWT end-to-end.
|
static EducationTokenValidationResult |
validateEducationToken(java.lang.String serverToken)
Validate an education server token signed by Microsoft's MESS service.
|
static ChainValidationResult |
validatePayload(org.cloudburstmc.protocol.bedrock.data.auth.AuthPayload payload) |
static ChainValidationResult |
validateToken(org.cloudburstmc.protocol.bedrock.data.auth.AuthType type,
java.lang.String token) |
static byte[] |
verifyClientData(java.lang.String clientDataJwt,
java.security.PublicKey identityPublicKey) |
static byte[] |
verifyClientData(java.lang.String clientDataJwt,
java.lang.String identityPublicKey) |
public static final java.lang.String ALGORITHM_TYPE
public static java.security.interfaces.ECPublicKey parseKey(java.lang.String b64)
throws java.security.NoSuchAlgorithmException,
java.security.spec.InvalidKeySpecException
b64 - base 64 encoded keyjava.security.NoSuchAlgorithmException - runtime does not support the EC key specjava.security.spec.InvalidKeySpecException - input does not conform with EC key specpublic static java.security.KeyPair createKeyPair()
public static byte[] verifyClientData(java.lang.String clientDataJwt,
java.lang.String identityPublicKey)
throws java.security.NoSuchAlgorithmException,
java.security.spec.InvalidKeySpecException,
org.jose4j.lang.JoseException
java.security.NoSuchAlgorithmExceptionjava.security.spec.InvalidKeySpecExceptionorg.jose4j.lang.JoseExceptionpublic static byte[] verifyClientData(java.lang.String clientDataJwt,
java.security.PublicKey identityPublicKey)
throws org.jose4j.lang.JoseException
org.jose4j.lang.JoseExceptionpublic static ChainValidationResult validatePayload(org.cloudburstmc.protocol.bedrock.data.auth.AuthPayload payload) throws org.jose4j.lang.JoseException, java.security.NoSuchAlgorithmException, java.security.spec.InvalidKeySpecException, org.jose4j.jwt.consumer.InvalidJwtException
org.jose4j.lang.JoseExceptionjava.security.NoSuchAlgorithmExceptionjava.security.spec.InvalidKeySpecExceptionorg.jose4j.jwt.consumer.InvalidJwtExceptionpublic static ChainValidationResult validateChain(java.util.List<java.lang.String> chain) throws org.jose4j.lang.JoseException, java.security.NoSuchAlgorithmException, java.security.spec.InvalidKeySpecException
org.jose4j.lang.JoseExceptionjava.security.NoSuchAlgorithmExceptionjava.security.spec.InvalidKeySpecExceptionpublic static ChainValidationResult validateToken(org.cloudburstmc.protocol.bedrock.data.auth.AuthType type, java.lang.String token) throws org.jose4j.jwt.consumer.InvalidJwtException, org.jose4j.lang.JoseException
org.jose4j.jwt.consumer.InvalidJwtExceptionorg.jose4j.lang.JoseExceptionpublic static javax.crypto.SecretKey getSecretKey(java.security.PrivateKey localPrivateKey,
java.security.PublicKey remotePublicKey,
byte[] token)
throws java.security.InvalidKeyException
localPrivateKey - local private keyremotePublicKey - remote public keytoken - token generated or received from the serverjava.security.InvalidKeyException - keys provided are not EC specpublic static java.lang.String createHandshakeJwt(java.security.KeyPair serverKeyPair,
byte[] token)
throws org.jose4j.lang.JoseException
ServerToClientHandshakePacket
which completes the encryption handshake.serverKeyPair - used to sign the JWTtoken - salt for the encryption handshakeorg.jose4j.lang.JoseException - invalid key pair providedpublic static java.lang.String createHandshakeJwt(java.security.KeyPair serverKeyPair,
byte[] token,
java.lang.String signedToken)
throws org.jose4j.lang.JoseException
ServerToClientHandshakePacket
which completes the encryption handshake.
For Education Edition clients, the signedToken parameter must contain the
education server token. Education clients verify this token during the handshake
and reject the connection if it is missing or invalid.
serverKeyPair - used to sign the JWTtoken - salt for the encryption handshakesignedToken - education server token, or null for standard Bedrockorg.jose4j.lang.JoseException - invalid key pair providedpublic static byte[] generateRandomToken()
SecureRandompublic static java.security.interfaces.ECPublicKey getMojangPublicKey()
public static java.security.PublicKey getEducationPublicKey()
public static EducationTokenValidationResult validateEducationPayload(java.lang.String eduTokenChain) throws org.jose4j.lang.JoseException, java.security.NoSuchAlgorithmException, java.security.InvalidKeyException
Education Edition clients send an outer self-signed JWT (the EduTokenChain) in place
of the standard Bedrock identity chain. Its payload carries a single chain
field containing the MESS-signed server token that actually proves player identity.
This method plays the same role for Education Edition that validatePayload(org.cloudburstmc.protocol.bedrock.data.auth.AuthPayload)
plays for standard Bedrock. It is the top-level entry point: it unwraps the outer
education JWT via extractServerTokenFromEduTokenChain(java.lang.String) and then verifies the
inner server token via validateEducationToken(java.lang.String).
eduTokenChain - the outer education login JWT as a compact serialization stringEducationTokenValidationResult.Status.INVALID
is returned if the JWT has no extractable server tokenorg.jose4j.lang.JoseException - the outer JWT is malformed or its payload is not valid JSONjava.security.NoSuchAlgorithmException - SHA256withRSA is not availablejava.security.InvalidKeyException - the education public key is not a valid RSA keypublic static java.lang.String extractServerTokenFromEduTokenChain(java.lang.String eduTokenChain)
throws org.jose4j.lang.JoseException
The EduTokenChain payload contains a chain field whose value is the
pipe-separated MESS-signed server token (tenantId|oid|expiry|signatureHex).
This method peels the JWT structure and returns that value without verifying anything.
Security: the outer JWT's signature is intentionally NOT verified here.
Education login JWTs are self-signed with an ephemeral client key, so verifying
the outer signature only proves the client signed its own JWT and establishes
nothing about player identity. The inner chain field is the load-bearing
credential and carries its own MESS RSA signature, which is verified by
validateEducationToken(java.lang.String). Any caller that extracts additional fields from
the outer JWT must treat those fields as untrusted unless a separate verification
path is established for them.
eduTokenChain - the outer education login JWT as a compact serialization stringnull if the input is null/empty or the
chain field is absent or not a stringorg.jose4j.lang.JoseException - the input is not a valid JWT or its payload is not valid JSONpublic static EducationTokenValidationResult validateEducationToken(java.lang.String serverToken) throws java.security.NoSuchAlgorithmException, java.security.InvalidKeyException
Token format: tenantId|oid|expiry|signatureHex where the signature
is RSA PKCS#1 v1.5 SHA-256 over tenantId|oid|expiry as UTF-8 bytes.
This method plays the same role for Education Edition that
validateChain(List) plays for standard Bedrock. It verifies player
identity against EDUCATION_PUBLIC_KEY in the same manner that
validateChain verifies identity against MOJANG_PUBLIC_KEY.
This inner MESS signature is the sole cryptographic anchor for education player identity. Other apparent verification points in the education login flow do not provide identity proof:
ChainValidationResult.signed() returns false and the
chain's claims prove only that the client holds the private half of
a public key they themselves generated.extraData.identity is a client-generated
per-session UUID, unrelated to the Entra Object ID and unanchored
to any external authority.EduTokenChain JWT that wraps this token in the login
packet is itself signed with another client-generated key whose
public half is embedded inline via the x5u header, not
fetched from a remote trust anchor. Verifying the outer signature
proves only that the client signed its own wrapper. An attacker
who captures a valid inner token can re-wrap it with a fresh
ephemeral key and produce a structurally valid outer JWT without
Microsoft's involvement.tenantId|oid|expiry binds the
token to a fixed Microsoft-controlled trust anchor
(EDUCATION_PUBLIC_KEY).
Verifying it is the only mechanism that attests to player identity
against a party the client cannot impersonate.serverToken - the pipe-separated education server tokenjava.security.NoSuchAlgorithmException - SHA256withRSA is not availablejava.security.InvalidKeyException - the education public key is not a valid RSA keypublic static javax.crypto.Cipher createCipher(boolean gcm,
boolean encrypt,
javax.crypto.SecretKey key)