A random bearer token starts as bytes from SecureRandom; Base64 URL encoding only turns those bytes into transport-safe text.
Java SecureRandom token encoding: preserve unpredictable bytes in a URL-safe form
Generate before encoding
The fixture draws 32 bytes and encodes them without padding. The exact token changes on every run, so it reports only the resulting length and alphabet. The encoding does not add entropy, and a readable token is still a credential that must be protected from logs and referrers.
Token lifecycle covers storage and expiry. Base64 alphabets explains why a URL-safe token may not decode under a basic alphabet.
Treat collision policy separately
A large random space reduces accidental collisions, but an issuing service should still enforce uniqueness in its storage boundary. Hash stored bearer tokens when lookup design permits, and compare an incoming token under a defined authentication policy.
Working program
import java.security.SecureRandom;
import java.util.Base64;
public class RecoveryTokenText {
public static void main(String[] args) {
byte[] tokenBytes = new byte[32];
new SecureRandom().nextBytes(tokenBytes);
String token = Base64.getUrlEncoder().withoutPadding().encodeToString(tokenBytes);
System.out.println("characters=" + token.length());
System.out.println("urlSafe=" + token.matches("[A-Za-z0-9_-]+"));
}
}Output
characters=43
urlSafe=trueCost and ownership
Generating and encoding n bytes takes work and output storage proportional to n. Encoding expands 32 bytes to 43 unpadded URL-safe characters here; it does not make the token secret after disclosure. Avoid repeatedly constructing a generator for every token in a high-volume issuer.
Common Mistakes
- Do not use java.util.Random for a bearer credential.
- Do not log the token merely because it is printable.
- Do not confuse Base64 encoding with encryption or hashing.
Read next
Java SecureRandom: token entropy, encoding and comparison boundaries, base64 url vs basic, Java SHA-256: hash declared bytes, not an implicit string encoding, Java HTTPS project: a trusted local certificate and a rejected hostname.
