#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)