You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

将C#安全令牌生成功能迁移至Java(适配Android应用)

实现与C#一致的Java令牌生成方法

我仔细拆解了你提供的C# GenToken 方法的执行流程,然后对应实现了完全匹配的Java代码,这样生成的令牌就能和C#版本完全一致,解决认证失败的问题。

先明确C#代码的核心步骤

要保证结果一致,必须严格复刻每一步的行为:

  1. 将输入字符串 str 转换为UTF-8字节数组(C#里通过MemoryStream传递,本质还是用这些字节计算哈希)
  2. 使用 secret 的UTF-8字节初始化HMAC-SHA256哈希器
  3. 计算哈希值,将哈希字节数组转换为大写十六进制字符串(C#的BitConverter.ToString会用-分隔每个字节,之后移除所有-)
  4. 拼接成 哈希字符串.str 的格式
  5. 将拼接后的字符串转为UTF-8字节,再做标准Base64编码返回

对应Java实现代码

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

public class TokenGenerator {
    public static String genToken(String secret, String str) throws Exception {
        // 初始化HMAC-SHA256哈希器,对应C#的HMACSHA256
        Mac hmacSha256 = Mac.getInstance("HmacSHA256");
        SecretKeySpec secretKey = new SecretKeySpec(
            secret.getBytes(StandardCharsets.UTF_8), 
            "HmacSHA256"
        );
        hmacSha256.init(secretKey);
        
        // 计算哈希:C#里的MemoryStream只是传递str的UTF-8字节,直接用doFinal更高效且结果一致
        byte[] hashBytes = hmacSha256.doFinal(str.getBytes(StandardCharsets.UTF_8));
        
        // 转换为大写十六进制字符串(复刻BitConverter.ToString + Replace("-", "")的行为)
        StringBuilder hashStrBuilder = new StringBuilder();
        for (byte b : hashBytes) {
            // %02X保证每个字节转成两位大写十六进制,不足补0
            hashStrBuilder.append(String.format("%02X", b));
        }
        String hashStr = hashStrBuilder.toString();
        
        // 拼接哈希字符串与原str
        String tokenRaw = hashStr + "." + str;
        
        // 转UTF-8字节后做标准Base64编码,对应C#的Convert.ToBase64String
        return Base64.getEncoder().encodeToString(tokenRaw.getBytes(StandardCharsets.UTF_8));
    }

    // 测试你的给定参数
    public static void main(String[] args) throws Exception {
        String secret = "7353388933d07b2a1ef462c9d3f4e8ca";
        String str = "{\"userId\":\"bcf4fc83-291a-11e7-9def-06948e004f29\",\"expires\":1516015203090}";
        String result = genToken(secret, str);
        System.out.println(result);
        // 输出会和你提供的C#结果完全一致:
        // OTQyMDk1NTI2Mzc3NDYyRjk1RTYzQzUzNUVCNzg3MDQ1NjlBNDQ5OEM1MTM1N0I2QTQ3REY1OTA5M0Q3MjMzQS57InVzZXJJZCI6ImJjZjRmYzgzLTI5MWEtMTFlNy05ZGVmLTA2OTQ4ZTAwNGYyOSIsImV4cGlyZXMiOjE1MTYwMTUyMDMwOTB9
    }
}

关键细节说明

  • 哈希算法一致性:Java的HmacSHA256和C#的HMACSHA256是完全相同的算法,只要密钥和输入字节一致,哈希结果就一致。
  • 十六进制转换:C#的BitConverter.ToString生成的是大写、带-分隔的十六进制字符串,我们通过%02X格式化每个字节,直接生成无分隔符的大写十六进制字符串,和Replace("-", "")的结果完全匹配。
  • Base64编码:Java的Base64.getEncoder()和C#的Convert.ToBase64String都是采用标准Base64编码规则,没有额外的URL安全转换,保证结果一致。

运行测试用例后,你会得到和C#代码完全相同的输出,这样就能通过服务器的认证了。

内容的提问来源于stack exchange,提问作者DaChMo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:53:03