Warm tip: This article is reproduced from serverfault.com, please click

Basic Auth Authorization header and base 64 encoding

发布于 2020-12-04 12:37:22

I have a vendor that I wish to exchange data with. They want me to take the username and password that they gave me and use it on an Authorization header for a get request.

And now my dirty little secret. I've never created an Authorization header before.

So I do a bunch of research and figure out the following code.

public static final String          AUTH_SEPARATOR = ":";
private static final String         AUTH_TYPE = "Basic ";
public static final String          HEADER_AUTHORIZATION = "Authorization";

public static void addAuthHeader(Map<String, String> headers, String user, String password) {
    String secretKey = user
            + AUTH_SEPARATOR
            + password;
    byte[] tokenBytes = secretKey.getBytes();
    String token64 = Base64.getEncoder().encodeToString(tokenBytes);
    String auth = AUTH_TYPE + token64;
    headers.put(HEADER_AUTHORIZATION, auth);
}

I run it and I get no response back. Hmmm. So I go to open a support request with them and I want to create an example, so I open postman and use the APIs they gave me for postman. First, I run the one for the API I'm replicating and it works. Hmm.

So then I modify that API and use my username and password instead of the one included in the example and it works fine. Crikey!

So I bang around a bit and notice that the Base64 string in the auth created by postman is slightly different at the end than the one I created.

So, back to the research and all the code I find looks a lot like mine, although I had to update it some because of version differences. The string is still different and now I'm asking for help. Surely someone has solved this problem.

String from postman "Basic THVKZ...FvTg==" String from code above "Basic THVKZ...FvTiA="

How did I do something wrong and end up with only a three byte difference?

Questioner
Thom
Viewed
0
Thom 2020-12-04 22:22:17

The problem is caused by padding. I still don't understand exactly why, but the string I'm encoding is 49 bytes long, which is not evenly divisible by 3, which means that padding comes into play.

When I changed my code to the following:

    String token64 = Base64.getEncoder().withoutPadding().encodeToString(tokenBytes);

and then ran it, I got the same string minus the two == at the end that base64 uses as a pad character. Sending that to the server got the answer I was looking for.

Why do they call it software when it's so damned hard?