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

使用BouncyCastle实现AES CMAC:是否需转换提供的密钥?

问题核心与解决方案

你的代码里最关键的错误是直接把十六进制密钥字符串按UTF-8编码转成字节数组,这完全不符合十六进制密钥的解析逻辑。32个字符的十六进制字符串对应16个字节(每2个十六进制字符代表1个字节),而你现在的做法是把每个字符单独转成UTF-8字节,相当于生成了32个字节的错误密钥,这必然和C#端的密钥不匹配,导致CMAC结果错误。

正确的密钥转换方式

你需要把十六进制字符串解码成对应二进制字节数组,而非直接编码。用BouncyCastle自带的Hex工具类就能快速实现:

import org.bouncycastle.util.encoders.Hex;

// 替换原代码中的KeyParameter初始化逻辑
byte[] keyBytes = Hex.decode(KEY);
KeyParameter parameter = new KeyParameter(keyBytes);

如果不想依赖BouncyCastle的Hex类,也可以手动实现十六进制转字节数组的方法:

public static byte[] hexToByteArray(String hexStr) {
    int len = hexStr.length();
    byte[] result = new byte[len / 2];
    for (int i = 0; i < len; i += 2) {
        result[i / 2] = (byte) ((Character.digit(hexStr.charAt(i), 16) << 4)
                             + Character.digit(hexStr.charAt(i+1), 16));
    }
    return result;
}

关于Java byte有符号的问题

不用纠结Java byte是有符号、C#是无符号的差异——密码学算法处理的是字节的二进制原始值,符号只是语言层面的表示方式。比如C#里的0xFF(数值255)和Java里的(byte)0xFF(数值-1),二进制都是11111111,底层运算时完全等价。只要你的密钥字节数组和C#端的二进制值一致,计算出的CMAC结果就会相同。

修正密钥的转换方式后,再运行代码应该就能得到和C#端一致的签名结果了。

内容的提问来源于stack exchange,提问作者Antonio E.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 20:02:40