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

ECDSA密钥认证应用报java.security.InvalidKeyException求排查

问题分析与解决

异常信息

java.security.InvalidKeyException: IOException : algid parse error, not a sequence

核心错误点

你的代码存在三个关键错误,导致无法正确读取EC私钥:

  • 结束标记替换错误:私钥结束标记是-----END EC PRIVATE KEY-----,但代码里替换的是-----END PRIVATE KEY-----,残留的无效内容会导致Base64解码后格式错误。
  • KeyFactory算法错误:你使用的是ECDSA密钥,但代码中KeyFactory.getInstance("RSA")指定了RSA算法,应该改为"EC"。
  • 密钥格式不匹配:OpenSSL生成的BEGIN EC PRIVATE KEY是SEC1格式私钥,而PKCS8EncodedKeySpec仅支持PKCS8格式,两者不兼容。

修复方案

方案1:修改代码直接解析SEC1格式私钥

更新密钥处理类(建议重命名为ECKeyService更贴合功能):

import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import org.bouncycastle.openssl.PEMParser;
import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.security.PrivateKey;
import java.security.Security;

public class ECKeyService {

    static {
        // 添加BouncyCastle安全提供者
        Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
    }

    public static PrivateKey getPrivateKey(String fileName) throws IOException {
        try (BufferedReader reader = new BufferedReader(new FileReader(fileName));
             PEMParser pemParser = new PEMParser(reader)) {
            Object object = pemParser.readObject();
            JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC");
            return converter.getPrivateKey((PrivateKeyInfo) object);
        }
    }
}

需添加BouncyCastle依赖(Maven示例):

<dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bcprov-jdk15on</artifactId>
    <version>1.70</version>
</dependency>

方案2:将SEC1格式密钥转为PKCS8格式

用OpenSSL命令转换密钥:

openssl pkcs8 -topk8 -inform PEM -in private_key.pem -out private_key_pkcs8.pem -nocrypt

转换后的密钥以-----BEGIN PRIVATE KEY-----开头,修改原代码的错误点即可:

private static PrivateKey getPrivateKeyFromString(String key)
        throws NoSuchAlgorithmException, InvalidKeySpecException {
    String privateKeyPem = key;
    // 修正结束标记替换
    privateKeyPem = privateKeyPem.replace("-----BEGIN PRIVATE KEY-----", "");
    privateKeyPem = privateKeyPem.replace("-----END PRIVATE KEY-----", "");
    privateKeyPem = privateKeyPem.replace("\n", "");
    byte[] encoded = Base64.decodeBase64(privateKeyPem);
    // 改为EC算法
    KeyFactory kf = KeyFactory.getInstance("EC");
    PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encoded);
    return kf.generatePrivate(keySpec);
}

额外注意事项

  • JWTService中使用SignatureAlgorithm.ES256是正确的,对应secp256k1曲线,但解析公钥时也需使用EC算法而非RSA。
  • 建议将RSAService重命名为ECKeyService,避免算法类型混淆。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 02:32:34