SExprParser.parseSecretKey: java.io.IOException: обнаружен неизвестный символ: K

#java #cryptography #bouncycastle #gnupg

#java #криптография #bouncycastle #gnupg

Вопрос:

Я пытаюсь загрузить секретные ключи из D:UsersxxxxxAppDataRoaminggnupgprivate-keys-v1.d использование надувного замка bcprov-jdk15on-1.66.jar .

 import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

import org.bouncycastle.gpg.SExprParser;
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPSecretKey;
import org.bouncycastle.openpgp.operator.PBEProtectionRemoverFactory;
import org.bouncycastle.openpgp.operator.PGPDigestCalculatorProvider;
import org.bouncycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator;
import org.bouncycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder;
import org.bouncycastle.openpgp.operator.jcajce.JcePBEProtectionRemoverFactory;
import org.bouncycastle.util.encoders.Hex;

public class LoadKey {
    public static void main(String[] args) throws IOException, PGPException {
        String filePath = "D:\Users\XXXX\AppData\Roaming\gnupg\private-keys-v1.d\4B8379C14DED7818D546E3C4AF7F1D0DF5716BCD.key";
        String pass = "siv_test";
            PGPDigestCalculatorProvider calculatorProvider = new JcaPGPDigestCalculatorProviderBuilder()
                    .build();
            PBEProtectionRemoverFactory passphraseProvider = new JcePBEProtectionRemoverFactory(
                pass.toCharArray());
        InputStream in = new FileInputStream(filePath);


        PGPSecretKey key =

        new SExprParser(calculatorProvider).parseSecretKey(
                new BufferedInputStream(in), passphraseProvider,
                new JcaKeyFingerprintCalculator());

        System.out.println("Found key "
                  Hex.toHexString(key.getPublicKey().getFingerprint()));
            
        
    }
}
  

Но я получаю

Исключение в потоке «main» java.io.IOException: обнаружен неизвестный символ: K в org.bouncycastle.gpg.SXprUtils.skipOpenParenthesis(неизвестный источник) в org.bouncycastle.gpg.SExprParser.parseSecretKey(неизвестный источник)

gpg (GnuPG) 2.2.23

libgcrypt 1.8.6

Ответ №1:

Мне кажется, что SExprParse принимает только «необработанные» ключи pgp, а не «PEM».

Ключ в моем примере взят из надувного замка SExprTest.java итак, это образец ключа с паролем «fred«.

Поскольку ключ находится в двоичной форме, я использую a ByteArrayInputStream для обработки ключа, это ссылка на полный тест: https://github.com/bcgit/bc-java/blob/master/pg/src/test/java/org/bouncycastle/openpgp/test/SExprTest.java.

Программа успешно запущена и в конце выдает секретный ключ:

 Found key 228f5c0cd3e1d2716760770be5ac9684b1a77195
  

Возможно, один из наших экспертов по надувному замку сможет объяснить поведение немного лучше…

Вот код:

 import org.bouncycastle.gpg.SExprParser;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPSecretKey;
import org.bouncycastle.openpgp.operator.PBEProtectionRemoverFactory;
import org.bouncycastle.openpgp.operator.PGPDigestCalculatorProvider;
import org.bouncycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator;
import org.bouncycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder;
import org.bouncycastle.openpgp.operator.jcajce.JcePBEProtectionRemoverFactory;
import org.bouncycastle.util.encoders.Base64;
import org.bouncycastle.util.encoders.Hex;
import java.io.*;
import java.security.Security;

public class LoadKeySo4 {
    public static void main(String[] args) throws IOException, PGPException {
        Security.addProvider(new BouncyCastleProvider());
        //String filePath = "D:\Users\XXXX\AppData\Roaming\gnupg\private-keys-v1.d\4B8379C14DED7818D546E3C4AF7F1D0DF5716BCD.key";
        //String pass = "siv_test";
        byte[] key1 = Base64.decode(
                "KDIxOnByb3RlY3RlZC1wcml2YXRlLWtleSgzOnJzYSgxOm4yNTc6AOpclatE"
                          "WCIXSUA2y44L/jPGE1lU3d75nMN5 iJK/vXFGmQdvZWhewX2LSJ5vwpcLcQ1"
                          "u3QXRbOcY0o jRAER2vHZMEfyHfHir6QDibVTO5IOjLettW054hew/HoFbA2"
                          "v3t0BB2HERWMFO6WLrC7wBVpgL85m85VhE/OmZGIOY7bapQtULoTQQ5Fwr0n"
                          " zG3gujxDcmpcTouz0DPtVLvMERnHMtJ4GEccWfiFrGUnLbBnYCnnsNoV/0m"
                          "f/GseRltCnxPS2Fl rhdkPmxC0Dkv6naV NMiaZVk5FYdtY66xATvETv xTa"
                          "X8xHIhJc4CrR/e4T0VPBh/94o5nHL1cT6HcpKDE6ZTM6AQABKSg5OnByb3Rl"
                          "Y3RlZDI1Om9wZW5wZ3AtczJrMy1zaGExLWFlcy1jYmMoKDQ6c2hhMTg6vqXu"
                          "vvqQtUw4OjI3OTYxMzQ0KTE2OlYbNG/073BvJLzSjbvoxQYpNzM2OkcNABDe"
                          "gU7iUAJwVxNszEG ackC6qk7Y dQ6NN4Avy9pkGo Rufs0G4yjHhVQMkH0QF"
                          "Wrzf5GOvsvrJQyJGVLn2amz5KxU onNv66UVi4D3LlCOghDcGoe/V7hY zsh"
                          "GN7elPhnBYbk7X1Jb5D03YrCOOCTnGLTLMc7E5qy4YSyRWMzAGGj/jkcY/B "
                          "ZEeLkTlHsnnukIMb24 1/sZrsV57AaVPRZwgzInxDGC9Tkg4j6fsHvvVw6ZD"
                          "cm ET/YGOf1dhMKEq/7GXcd5qeEpMBFi 6p2PrPJUwUHu/PIOs1SCIYlrhGR"
                          "iifAHtOIdFGefo E1v6kKZMO FgLTeiGYN6T6vjkG7FMiWwnmamF6qNd1D5i"
                          "TS2E4uiS5Z3QuwyXJfGkYYDjEmV5rVSol95Kd4wpebC7mFNbOk zA4TB5Ytb"
                          "5KN/w2lSW4btuB/pD/akfg6xJQ9BREv1vpO4CtK d8VLCPHI7et1tKjwJNxd"
                          "obw9P4HOBIPYdzbHARpAfZRLQlLRNcYp8DbHfzmDhIEPymO6 3CCtdfRE7xY"
                          "c0SMpFFYGX17WGlmjdOYWtbqYrhDQ3ylzD3vrIQr12ZZXw00xSJkNk4aJ8Lx"
                          "SihOXTuLiHhueckfCCbkWPfdJQg1ukjRiNgHdEF 7rk/2aMDsSYULJqtjSed"
                          "CDi9tLqawmCz405E W Htbrp2yv7ktST2IaV56JQB4Yay8WAlnngoBtdlSyA"
                          "wFVFm5VrCeZ5ckdUfK1qSezd32uQlb27XCZYGiaco5AWkhBOrdPoiw4Z14Pf"
                          "z6xhhV vA X6lm9k70iG7RO9vf3V EAbKktFos72rGJGhWOZgv5xr8DRjbIf"
                          "/dOQsgceYg4xrTzn/SjOSNmTQu  Q1Uo5jjtMozgXawJNFPKcZ28DLTxdHQl"
                          "a7jZK/FiiXXBL8J/VbN9DWZq7IOUMEhRym8KcAoyC7wQgpua2qhp8EXX7Qqd"
                          "7dU4EcdWzzz/lF8pKDEyOnByb3RlY3RlZC1hdDE1OjIwMTgwNTI4VDAyMjIw"
                          "MikpKQ==");
        String pass = "fred";

        PGPDigestCalculatorProvider calculatorProvider = new JcaPGPDigestCalculatorProviderBuilder()
                .build();
        PBEProtectionRemoverFactory passphraseProvider = new JcePBEProtectionRemoverFactory(
                pass.toCharArray());
        //InputStream in = new FileInputStream(filePath);
        InputStream in = new ByteArrayInputStream(key1);
        PGPSecretKey key =
                new SExprParser(calculatorProvider).parseSecretKey(
                        new BufferedInputStream(in), passphraseProvider,
                        new JcaKeyFingerprintCalculator());
        System.out.println("Found key "
                  Hex.toHexString(key.getPublicKey().getFingerprint()));
    }
}
  

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

1. Здравствуйте, Майкл Фер, большое вам спасибо за ваш ответ. Но наша идея состоит в том, чтобы загрузить закрытый ключ для данного пользователя. Мой код отлично работает с GNUPG версии 2.1.X, поскольку он выдает исключение для GNUPG версии 2.2.X.

2. lists.gnupg.org/pipermail/gnupg-devel/2017-December/033295.html

3. Может быть, вы могли бы отредактировать свой вопрос и добавить образец ключа с GNUPG версии 2.2.X вместе с парольной фразой?