DaChMo
DaChMo

Reputation: 1

Recreating secure token functionality from C# into Java

I have an application I am converting from C# to Java (eventually I want to make this an android app).

To give some background: the application connects to a web server, with a JSON formatted request for a 'key' to log in. Within the JSON is a token which is generated by the following code:

public static string GenToken(string secret, string str)
    {
        string token;
        using (var stream = new System.IO.MemoryStream(Encoding.UTF8.GetBytes(str)))
        {

            using (var hmac = new System.Security.Cryptography.HMACSHA256(Encoding.UTF8.GetBytes(secret)))
            {
                var hash = hmac.ComputeHash(stream);        
                var hashStr = BitConverter.ToString(hash);        
                token = string.Format("{0}.{1}", hashStr.Replace("-", ""), str);

            }
        }

        return Convert.ToBase64String(Encoding.UTF8.GetBytes(token));
    }

The closest I have found is some code I found here but this is still not producing the same result as the C# code.

What I need is something that will produce the same result in Java as this bit of c# code. Otherwise the authentication fails.

For reference, I am testing using the values:

secret = 7353388933d07b2a1ef462c9d3f4e8ca;
str = {"userId":"bcf4fc83-291a-11e7-9def-06948e004f29","expires":1516015203090}

This outputs

OTQyMDk1NTI2Mzc3NDYyRjk1RTYzQzUzNUVCNzg3MDQ1NjlBNDQ5OEM1MTM1N0I2QTQ3REY1OTA5M0Q3MjMzQS57InVzZXJJZCI6ImJjZjRmYzgzLTI5MWEtMTFlNy05ZGVmLTA2OTQ4ZTAwNGYyOSIsImV4cGlyZXMiOjE1MTYwMTUyMDMwOTB9 

EDIT I have gotten as far as realising that

using (var stream = new System.IO.MemoryStream(Encoding.UTF8.GetBytes(str)))

Is producing a hex value of

 7B-22-75-73-65-72-49-64-22-3A-22-62-63-66-34-66-63-38-33-2D-32-39-31-61-2D-31-31-65-37-2D-39-64-65-66-2D-30-36-39-34-38-65-30-30-34-66-32-39-22-2C-22-65-78-70-69-72-65-73-22-3A-31-35-31-36-30-31-35-32-30-33-30-39-30-7D

Which I have been able to do with the following in Java (removing the need to replace the dashes)

public static String toHex(String arg) {
    return String.format("%040X", new BigInteger(1, arg.getBytes(StandardCharsets.UTF_8)));
}

But I'm well and truly stuck after this point.

Thanks in advance

Upvotes: 0

Views: 116

Answers (1)

Martijn
Martijn

Reputation: 5611

The C# code:

  1. converts the hash to its hexadecimal representation hashStr. To convert a byte array to a hexadecimal string in Java see this post.
  2. removes "-" that were introduced by BitConverter. You won't need to do this in Java, since adding "-" is specific to BitConverter.
  3. concatenates hashStr and str with a dot in between to get a token. This is trivial in Java: token = hashStr + "." + str.
  4. converts the token to a base64 encoding. To do this in Java, use Base64.encodeBase64String as was done in your example

The code you're referring to does not perform these steps. Did you consider adding these steps to the Java code?

Upvotes: 1

Related Questions