Java导入ECDSA算法PGP公钥返回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

