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
相关产品推荐
相关产品推荐

