BouncyCastle — GPG. Извлечение открытого ключа из секретного ключа

#java #bouncycastle #gnupg

#java #bouncycastle #gnupg

Вопрос:

Я использую этот Java-код для извлечения открытого ключа из секретного ключа:

 PGPSecretKeyRingCollection ring = new PGPSecretKeyRingCollection(decoderStream,
            new JcaKeyFingerprintCalculator());
Iterator<PGPSecretKeyRing> it = ring.getKeyRings();
while (it.hasNext()) {
    PGPSecretKeyRing key = it.next();
    Iterator<PGPPublicKey> itpublic = key.getPublicKeys();
    while (itpublic.hasNext()) {
        PGPPublicKey pubKey = itpublic.next();
        // use this pubKey
    }
}
  

Если я попытаюсь экспортировать этот ключ в ArmoredOutputStream, я получу что-то вроде:

     -----BEGIN PGP PUBLIC KEY BLOCK-----
    Version: BCPG v1.66
    
    hQEMA6GfAr1vmvVrAQf/XF/6DqSxZu0dXXVnhfxoot YTLBrwnec/af72R8G1aJI
    [...]
    =eLkg
    -----END PGP PUBLIC KEY BLOCK-----
  

Если я использую этот ключ для шифрования чего-либо из кода Java, все работает нормально.

Если я использую этот ключ для шифрования файлов из командной строки (или других клиентов, таких как Kleopatra):

 $ gpg --import pubKey.gpg
$ gpg --encrypt ...
  

Я получаю ошибку «Непригодный для использования открытый ключ».

Я делаю что-то не так с экспортом открытого ключа из кода Java?

Комментарии:

1. Я не знаю, как это связано с вашей конкретной проблемой, но в целом вся идея асимметричной криптографии заключается в генерации пары ключей, обладающих таким свойством, что вы НЕ можете генерировать один из другого.

2. С помощью клиента GPG вы можете импортировать секретный ключ, а затем экспортировать открытый ключ из этого файла

Ответ №1:

Вы должны использовать весь PublicKeyRing, а не только главный открытый ключ:

 List<PGPPublicKey> list = new ArrayList<>();
Iterator<PGPSecretKeyRing> it = ring.getKeyRings();
while (it.hasNext()) {
    PGPSecretKeyRing secretRing = it.next();
    Iterator<PGPPublicKey> itpublic = secretRing.getPublicKeys();
    while (itpublic.hasNext()) {
        PGPPublicKey pub = itpublic.next();
        list.add(pub);
    }
    Iterator<PGPPublicKey> itextrapublic = secretRing.getExtraPublicKeys();
    while (itextrapublic.hasNext()) {
        PGPPublicKey pub = itextrapublic.next();
        list.add(pub);
    }
}
PGPPublicKeyRing publicRing = new PGPPublicKeyRing(list);
publicRing.encode(armoredOutputStream)