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

Java导入ECDSA算法PGP公钥返回null问题求助

Issue Reading ECDSA PGP Public Key (Returns Null)

Let's break down why your current method is returning null for the ECDSA key, and how to fix it.

The Root Cause

Your code filters keys using k.isEncryptionKey(), but ECDSA is a signature-only algorithm in PGP—it doesn't support encryption. Encryption with ECC in PGP uses ECDH (Elliptic Curve Diffie-Hellman) instead.

Looking at your provided public key, it's likely only configured with an ECDSA signing key, not an encryption key. That's why your loop never finds a matching key and throws the exception.

Solution 1: Adjust the Key Filter for Signing Scenarios

If you're trying to use this key to verify signatures (the primary use case for ECDSA), modify your key check to look for signing keys instead:

public static PGPPublicKey readPublicKey(InputStream in) throws IOException, PGPException {
    in = org.bouncycastle.openpgp.PGPUtil.getDecoderStream(in);
    PGPPublicKeyRingCollection pgpPub = new PGPPublicKeyRingCollection(in);

    PGPPublicKey key = null;

    Iterator<PGPPublicKeyRing> rIt = pgpPub.getKeyRings();
    while (key == null && rIt.hasNext()) {
        PGPPublicKeyRing kRing = rIt.next();
        Iterator<PGPPublicKey> kIt = kRing.getPublicKeys();
        while (key == null && kIt.hasNext()) {
            PGPPublicKey k = kIt.next();
            // Check for signing keys instead (or both, if needed)
            if (k.isSigningKey()) {
                key = k;
            }
        }
    }

    if (key == null) {
        throw new IllegalArgumentException("Can't find signing key in key ring.");
    }
    return key;
}

Solution 2: Ensure You Have an Encryption Key (For Encryption Scenarios)

If you need to use this key for encrypting data, you'll need to generate a key pair that includes an ECDH encryption subkey (since ECDSA can't handle encryption). Most PGP tools let you add an encryption subkey to an existing key ring if needed.

Debugging Step

To confirm what types of keys are in your key ring, you can add a quick debug loop to print key properties:

// Inside your key iteration loop
PGPPublicKey k = kIt.next();
System.out.println("Key ID: " + Long.toHexString(k.getKeyID()));
System.out.println("Is encryption key: " + k.isEncryptionKey());
System.out.println("Is signing key: " + k.isSigningKey());

This will show you exactly what key types your ring contains, helping you confirm the issue.


Original Context

I'm trying to import an existing PGP public key (generated with ECDSA):

-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: Keybase OpenPGP v1.0.0
Comment: https://keybase.io/crypto
xm8EXtFujBMFK4EEACIDAwQNLpTSC8Tvvve477Qw8YLe7toYxzYgDQRQbcaIajuF
QwWbnns+gZ9EDKIijcmi80QYPICDzrxKCaUOIIN+4//AUkCULovLC67qoEkcgDBY
Zig7GIoTPPYHVgEwr9baTqrNHGl2YW4gPGl2YWxiZXJ0bzg5QGdtYWlsLmNvbT7C
jwQTEwoAFwUCXtFujAIbLwMLCQcDFQoIAh4BAheAAAoJEO8cm+rVKFm/INMBgLQn
5itjscBcGoK605Wlsmk0lmTFK2qE7GmhFsFVg4Ut3vL2BjFBtlSzj21CH8bneQGA
1Btl14COww3h2u0rZY7HcsgzsWV8gaKBfAN/KpmOfxXqZ7HqrNc7o4XuXJH5QVrC
zlIEXtFujBMIKoZIzj0DAQcCAwS8t6iC+Ik9ZbgOY2JwmC8eILILiu3HUM/mqa4q
zBNe+gWgpHPNBjPHJKDYCTByy6UAb3eJHCjJZOj6ZU4BdmfPwsAnBBgTCgAPBQJe
0W6MBQkPCZwAAhsuAGoJEO8cm+rVKFm/XyAEGRMKAAYFAl7RbowACgkQUa2LyJhX
0c/6qQD/WWZpNX0O/k6kYrzK1i/xk0NBLLb4nNq0OB04x7gWuGoBAOPpxjoqRURV
0Hozha+XV9u1aTq+fOMDZxTNgL5FG0KGo4cBf0vATKVZw9wcq+s4mZIXZxs4rAod
Fe5fLgpzZvT/RIHVIU6uJieUsee4hgs0H2ErwGAihWWRrnmaJcsaKC9rq2na3fr
X6BcXRlGbavVofoX+nPyJKDDayHXZ2m4jmgllZe+zlIEXtFujBMIKoZIzj0DAQcC
AwTFxy3Kjj8Jy/fW5W21oG6+aY/ekTChtUANz28MiUvy1de4DYZkFxukRzudT3ij
c2zzsi8UBN02q2cvqY0luAvEwsAnBBgTCgAPBQJe0W6MBQkPCZwAAhsuAGoJEO8c
m+rVKFm/XyAEGRMKAAYFAl7RbowACgkQ103VlblSzhyRKAD/ac/TbN5EaFNdEMWn
28OW8uiDbKl/39EYVE/yr6DjQigA/0VkcoPWN3eVxj44d/cAWhRbWqoy04A+lRtC
wAEV6VXNOdUBgN4AuhF9urpqXFfJ/1s1G8GbRzY0wTpHuZEAjyrBtC+hBgVN0Us7
OYpM6CC6dXOejwGAurQgQOH/i++M8olxZAEnVj0vrP93hjs90N8DbtuIc/7Beb6o
uJ9OEwREoizWqTdn
=4fnu
-----END PGP PUBLIC KEY BLOCK-----

But the retrieved public key is always null. The key was generated with ECDSA, and I can view its parameters on the keyProperties page.

Here's my current method for reading public keys, which works for RSA keys:

public static PGPPublicKey readPublicKey(InputStream in) throws IOException, PGPException {
    in = org.bouncycastle.openpgp.PGPUtil.getDecoderStream(in);
    PGPPublicKeyRingCollection pgpPub = new PGPPublicKeyRingCollection(in);

    PGPPublicKey key = null;

    Iterator<PGPPublicKeyRing> rIt = pgpPub.getKeyRings();
    while (key == null && rIt.hasNext()) {
        PGPPublicKeyRing kRing = rIt.next();
        Iterator<PGPPublicKey> kIt = kRing.getPublicKeys();
        while (key == null && kIt.hasNext()) {
            PGPPublicKey k = kIt.next();
            if (k.isEncryptionKey()) {
                key = k;
            }
        }
    }

    if (key == null) {
        throw new IllegalArgumentException("Can't find encryption key in key ring.");
    }
    return key;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 20:52:37