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

Java加载Ed25519公钥时遇缓冲区长度异常求助

Java加载Ed25519公钥时出现“缓冲区必须为32长度”异常

问题背景

需要在Java中使用BouncyCastle库读取并加载Ed25519公钥以验证签名,输入令牌格式为{public_key}/message.signature,示例令牌如下:

6a3239269f93999baec60382189c718031ad22c4c807ff29417824132cf0aa2d/eyJpc3N1ZV9kYXRlIjogIjIwMjItMTAtMjMiLCAiZXhwaXJ5X2RhdGUiOiAiMjAyMi0xMS0yMyIsICJsaWNlbnNlX3R5cGUiOiAxLCAibGljZW5zZV9rZXkiOiAiOTczZTIxOWVlNDg5NDVlNmViMDhjYzQzM2QyYjBjMDUifQ==.122ff0664a54122c6929183a561bb211a4168801e5917f33b69231eea56205ae32af4804a69a9fd25c6fab4bbf44048b57b11d71c5b8fe4fb153d0f45c5e140f

该令牌由Python的ed25519库生成,生成代码如下:

private_key, public_key = ed25519.create_keypair()
public_key_string = public_key.to_ascii(encoding='hex').decode('utf-8')
signature = private_key.sign(json_string.encode('utf-8'), encoding='hex')
token = public_key_string + '/' + \
        base64.b64encode(json_string.encode('utf-8')).decode('utf-8') + \
        '.' + signature.decode('utf-8')

在Java中拆分令牌并加载公钥时,抛出“缓冲区必须为32长度”异常(可见公钥字符串长度为64)。

问题原因

Python代码中public_key.to_ascii(encoding='hex')生成的是十六进制编码的字符串:Ed25519公钥本身是32字节的二进制数据,转成十六进制后每个字节对应2个字符,所以最终是64位的字符串。而Java中BouncyCastle的Ed25519公钥加载接口(如Ed25519PublicKeyParameters的构造方法)需要的是原始的32字节二进制数据,直接传入64位的十六进制字符串会导致长度不匹配,抛出异常。

解决方法

需要先将十六进制编码的公钥字符串解码为32字节的二进制数组,再用该数组初始化Ed25519公钥。示例代码如下:

import org.bouncycastle.crypto.params.Ed25519PublicKeyParameters;
import org.bouncycastle.util.encoders.Hex;

// 从令牌中拆分出公钥的十六进制字符串
String publicKeyHex = "6a3239269f93999baec60382189c718031ad22c4c807ff29417824132cf0aa2d";
// 将十六进制字符串解码为32字节的二进制数组
byte[] publicKeyBytes = Hex.decode(publicKeyHex);
// 初始化Ed25519公钥参数
Ed25519PublicKeyParameters publicKey = new Ed25519PublicKeyParameters(publicKeyBytes, 0);

额外注意点

  • 签名部分同样是十六进制字符串,验证签名前需要用Hex.decode()转成字节数组。
  • message部分是Base64编码,需要先解码为原始的JSON字节数据,再作为待验证的内容传入签名验证方法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 16:21:10