Initial commit: Spotify MC client-side Fabric mod for Minecraft 1.21.1
This commit is contained in:
commit
32f8428ddb
32 files changed
+3643
No files matched your search
@@ -0,0 +1,70 @@
|
||||
package com.spotifymc.auth;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Base64;
|
||||
|
||||
/**
|
||||
* Utility class for generating OAuth 2.0 PKCE (Proof Key for Code Exchange)
|
||||
* verifiers and SHA-256 code challenges per RFC 7636.
|
||||
*/
|
||||
public final class PkceUtils {
|
||||
|
||||
private static final SecureRandom RANDOM = new SecureRandom();
|
||||
private static final String UNRESERVED_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~";
|
||||
|
||||
private PkceUtils() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a cryptographically secure random code verifier string.
|
||||
*
|
||||
* @param length The length of the verifier (between 43 and 128 characters).
|
||||
* @return The randomly generated code verifier.
|
||||
*/
|
||||
public static String generateCodeVerifier(int length) {
|
||||
if (length < 43 || length > 128) {
|
||||
throw new IllegalArgumentException("Verifier length must be between 43 and 128 characters");
|
||||
}
|
||||
StringBuilder sb = new StringBuilder(length);
|
||||
for (int i = 0; i < length; i++) {
|
||||
int index = RANDOM.nextInt(UNRESERVED_CHARS.length());
|
||||
sb.append(UNRESERVED_CHARS.charAt(index));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a 64-character code verifier (recommended default length).
|
||||
*/
|
||||
public static String generateCodeVerifier() {
|
||||
return generateCodeVerifier(64);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a code challenge from the given verifier using SHA-256 and Base64URL encoding (without padding).
|
||||
*
|
||||
* @param codeVerifier The PKCE code verifier.
|
||||
* @return Base64URL-encoded SHA-256 code challenge.
|
||||
*/
|
||||
public static String generateCodeChallenge(String codeVerifier) {
|
||||
try {
|
||||
MessageDigest digest = MessageDigest.getInstance("SHA-256");
|
||||
byte[] hash = digest.digest(codeVerifier.getBytes(StandardCharsets.US_ASCII));
|
||||
return Base64.getUrlEncoder().withoutPadding().encodeToString(hash);
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new RuntimeException("SHA-256 message digest algorithm not available", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a random state string to prevent Cross-Site Request Forgery (CSRF).
|
||||
*/
|
||||
public static String generateState() {
|
||||
byte[] bytes = new byte[16];
|
||||
RANDOM.nextBytes(bytes);
|
||||
return Base64.getUrlEncoder().withoutPadding().encodeToString(bytes);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user