Cryptopals first challenge - hexadecimal to base64
That is a very pure solution that does not use any available feature. It is a solid solution.

However everything is String, even the conversion from a byte as two hexadecimal digits uses integer, but converts it back to a string.

The same code style of yours would allow immediately convert every hexadecimal digit to 4 bits.

    final String[] nibbles = { "0000", "0001", "0010", "0011",
            "0100", "0101", "0110", "0111",
            "1000", "1001", "1010", "1011",
            "1100", "1101", "1110", "1111" };
    int nbitsRaw = hex.length() * 4;

    // Make nbits a multiple of 6 
    int nbits += (6 - (nbitsRaw % 6)) % 6;
    StringBuilder sb = new StringBuilder(nbits);
    hex.codePoints()
            .forEach(hexdigit -&gt; {
                int value = hexdigit &lt;= '9' ? hexdigit - '0' : 9 + (hexdigit &amp; 0xF); // 0-9A-Fa-F
                sb.append(nibbles[value]);
            });
    for (int i = nbitsRaw; i &lt; nbits; ++i) {
        sb.append('0');
    }


Best of course would be using the bits in an int, not needing to juggle string constants of binary numbering. Especially the loops hurt. One would indeed far better use a Map&lt;String, Character&gt; but I understand your requirement of not using any higher construct.

The code is necessarily slow. You can try a longer input, and will probably have to wait for a result.

String concatenation is slow; char[] or StringBuilder would be advisable.
One can always do new String(charArray).

Stylistic:


hextobase64 by java camel case convention: hexToBase64
conversion no-namer: hexByteToBits
The constants could be fields private static final String[] BASE64 i.o. base64.