如何从GCP KMS的ECDSA签名字节数组提取{r,s}整数对?
将GCP KMS返回的ECDSA签名字节数组解析为{r, s}整数对
你通过GCP KMS获取的ECDSA签名字节数组,本质是ASN.1 DER编码格式,要提取出{r, s}整数对,需要解析这个DER结构。以下是具体实现步骤和代码:
前提准备
如果使用BouncyCastle库处理ASN.1解析,先添加Maven依赖:
<dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcprov-jdk15on</artifactId> <version>1.70</version> </dependency>
解析代码实现
import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Sequence; import java.io.IOException; import java.math.BigInteger; // 假设signature是从KMS获取的签名字节数组 byte[] signature = result.getSignature().toByteArray(); try (ASN1InputStream asn1InputStream = new ASN1InputStream(signature)) { // 解析DER序列,ECDSA签名的DER结构是SEQUENCE包含两个INTEGER ASN1Sequence sequence = (ASN1Sequence) asn1InputStream.readObject(); ASN1Integer rAsn1 = (ASN1Integer) sequence.getObjectAt(0); ASN1Integer sAsn1 = (ASN1Integer) sequence.getObjectAt(1); // 转换为BigInteger类型的r和s BigInteger r = rAsn1.getPositiveValue(); BigInteger s = sAsn1.getPositiveValue(); // 此时r和s就是你需要的ECDSA签名整数对 System.out.println("r: " + r.toString(16)); System.out.println("s: " + s.toString(16)); } catch (IOException e) { e.printStackTrace(); }
关键说明
- GCP KMS生成的ECDSA签名遵循ITU-T X.690 DER编码规范,结构为:
SEQUENCE { r INTEGER, s INTEGER } - 使用
getPositiveValue()确保获取的是无符号正整数,避免因字节最高位为1导致的负数问题 - 如果不想引入第三方库,也可以用JDK自带的
java.security.spec.ECSignature相关类手动解析,但实现复杂度更高,推荐使用BouncyCastle简化开发
内容的提问来源于stack exchange,提问作者neo007
相关产品推荐
相关产品推荐

