将安全令牌功能从C#重新创建到Java中

时间:2018-01-19 10:31:43

标签: java c# base64 sha256

我有一个应用程序,我正在从C#转换为Java(最终我想让它成为一个Android应用程序)。

为了给出一些背景知识:应用程序连接到Web服务器,其中包含一个JSON格式的'键'登录。在JSON中是一个由以下代码生成的令牌:

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));
    }

我找到的最接近的是我找到的一些代码here,但这仍然没有产生与C#代码相同的结果。

我需要的东西会在Java中产生与c#代码相同的结果。否则验证失败。

作为参考,我正在测试使用值:

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

此输出

OTQyMDk1NTI2Mzc3NDYyRjk1RTYzQzUzNUVCNzg3MDQ1NjlBNDQ5OEM1MTM1N0I2QTQ3REY1OTA5M0Q3MjMzQS57InVzZXJJZCI6ImJjZjRmYzgzLTI5MWEtMTFlNy05ZGVmLTA2OTQ4ZTAwNGYyOSIsImV4cGlyZXMiOjE1MTYwMTUyMDMwOTB9 

修改 我已经意识到这一点

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

生成十六进制值

 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

我在Java中可以使用以下内容(无需替换破折号)

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

但是在这一点之后,我确实陷入了困境。

提前致谢

1 个答案:

答案 0 :(得分:1)

C#代码:

  1. 将哈希值转换为十六进制表示hashStr。要在Java中将字节数组转换为十六进制字符串,请参阅this post。
  2. 删除" - "由BitConverter引入的。您不需要在Java中执行此操作,因为添加" - "特定于BitConverter。
  3. hashStrstr连接在一起,以获得token。这在Java中是微不足道的:token = hashStr + "." + str
  4. 将令牌转换为base64编码。要在Java中执行此操作,请使用Base64.encodeBase64String
  5. 中的{{1}}

    example要执行的代码不会执行这些步骤。您是否考虑将这些步骤添加到Java代码中?