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

如何从Java Bouncy Castle库提取ECDSA原始公私钥适配C端原生格式

ECDSA secp256r1 原始密钥导出方案(适配C端32/64字节格式)

你之前的推测完全正确,默认JCE的PublicKey.getEncoded()输出为带元数据的X.509 SubjectPublicKeyInfo封装格式,PrivateKey.getEncoded()为带元数据的PKCS#8封装格式,需要提取原始椭圆曲线参数得到裸密钥,具体实现如下:


工具方法(处理BigInteger转固定长度字节数组)

解决BigInteger自带符号位、输出长度不固定的问题:

// 把BigInteger转换为指定长度的无符号大端字节数组,自动补前导0或裁剪多余符号位
private static byte[] toUnsignedFixedLengthByteArray(BigInteger bi, int length) {
    byte[] array = bi.toByteArray();
    if (array.length == length) {
        return array;
    }
    // 去掉多余的符号位前缀0
    if (array.length == length + 1 && array[0] == 0) {
        byte[] trimmed = new byte[length];
        System.arraycopy(array, 1, trimmed, 0, length);
        return trimmed;
    }
    // 长度不足时补前导0
    if (array.length < length) {
        byte[] padded = new byte[length];
        System.arraycopy(array, 0, padded, length - array.length, array.length);
        return padded;
    }
    throw new IllegalArgumentException("BigInteger长度超出预期的" + length + "字节");
}

原始公钥导出方法

输出64字节原始公钥,结构为32字节X坐标 + 32字节Y坐标,完全匹配C端格式要求:

public static byte[] getRawECPublicKey(PublicKey publicKey) {
    ECPublicKey ecPublicKey = (ECPublicKey) publicKey;
    ECPoint point = ecPublicKey.getW();
    byte[] x = toUnsignedFixedLengthByteArray(point.getAffineX(), 32);
    byte[] y = toUnsignedFixedLengthByteArray(point.getAffineY(), 32);
    byte[] rawPub = new byte[64];
    System.arraycopy(x, 0, rawPub, 0, 32);
    System.arraycopy(y, 0, rawPub, 32, 32);
    return rawPub;
}

原始私钥导出方法

输出32字节原始私钥,对应EC参数中的S值:

public static byte[] getRawECPrivateKey(PrivateKey privateKey) {
    ECPrivateKey ecPrivateKey = (ECPrivateKey) privateKey;
    return toUnsignedFixedLengthByteArray(ecPrivateKey.getS(), 32);
}

使用示例

public static void main(String[] args) throws Exception {
    KeyPair vendorKeys = GenerateKeys();
    byte[] rawPublicKey = getRawECPublicKey(vendorKeys.getPublic());
    byte[] rawPrivateKey = getRawECPrivateKey(vendorKeys.getPrivate());
    
    System.out.println("原始公钥长度:" + rawPublicKey.length); // 输出64
    System.out.println("原始私钥长度:" + rawPrivateKey.length); // 输出32
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 01:36:04