Невозможно расшифровать зашифрованный файл PGP CAST5 с помощью библиотек Bouncy Castle в Java 8 - PullRequest
2 голосов
/ 07 февраля 2020

Мы используем библиотеки Bouncy Castle Java для расшифровки PGP, и все работало хорошо, пока мы не достигли точки, где нам пришлось расшифровывать файл со следующими атрибутами (фрагмент из pgpdump <filename> output)

> pgpdump file-name.csv.pgp                                                                                                          
New: Symmetric-Key Encrypted Session Key Packet(tag 3)(29 bytes)
    New version(4)
    Sym alg - CAST5(sym 3)
    Salted string-to-key(s2k 1):
        Hash alg - SHA1(hash 2)
        Salt - c3 89 7b 22 c0 90 a2 1f 
    Encrypted session key
        -> sym alg(1 bytes) + session key
New: Public-Key Encrypted Session Key Packet(tag 1)(268 bytes)
    New version(3)
    Key ID - 0x00FB426B9D39D2D9
    Pub alg - RSA Encrypt or Sign(pub 1)
    RSA m^e mod n(2048 bits) - ...
        -> m = sym alg(1 byte) + checksum(2 bytes) + PKCS-1 block type 02
New: Public-Key Encrypted Session Key Packet(tag 1)(268 bytes)
    New version(3)
    Key ID - 0x13BCC3DF42A3585C
    Pub alg - RSA Encrypt or Sign(pub 1)
    RSA m^e mod n(2048 bits) - ...
        -> m = sym alg(1 byte) + checksum(2 bytes) + PKCS-1 block type 02
New: Symmetrically Encrypted and MDC Packet(tag 18)(8192 bytes) partial start
    Ver 1
    Encrypted data [sym alg is specified in pub-key encrypted session key]
        (plain text + MDC SHA1(20 bytes))

Я могу расшифровать файл на моей ма c, используя

gpg --passphrase <passphrase> -v -d --pinentry-mode=loopback -o foo.out

Используя java код ниже на основе примера BouncyCastle , я заканчиваю org.bouncycastle.openpgp.PGPException: Exception creating cipher CAST5.

public static byte[] decrypt(
        byte[] encrypted,
        char[] passPhrase)
        throws IOException, PGPException, NoSuchProviderException
    {
        InputStream in = new ByteArrayInputStream(encrypted);

        in = PGPUtil.getDecoderStream(in);

        PGPObjectFactory         pgpF = new PGPObjectFactory(in);
        PGPEncryptedDataList     enc;
        Object                          o = pgpF.nextObject();

        //
        // the first object might be a PGP marker packet.
        //
        if (o instanceof PGPEncryptedDataList)
        {
            enc = (PGPEncryptedDataList)o;
        }
        else
        {
            enc = (PGPEncryptedDataList)pgpF.nextObject();
        }

        PGPPBEEncryptedData pbe = (PGPPBEEncryptedData)enc.get(0);

        //****************************************
        // Hitting an exception here while doing pbe.getDataStream()... 
        // Getting  "org.bouncycastle.openpgp.PGPException: Exception creating cipher CAST5"
        //****************************************
        InputStream clear = pbe.getDataStream(new JcePBEDataDecryptorFactoryBuilder(new JcaPGPDigestCalculatorProviderBuilder().setProvider("BC").build()).setProvider("BC").build(passPhrase)); 

        PGPObjectFactory        pgpFact = new PGPObjectFactory(clear);

        PGPCompressedData   cData = (PGPCompressedData)pgpFact.nextObject();

        pgpFact = new PGPObjectFactory(cData.getDataStream());

        PGPLiteralData ld = (PGPLiteralData)pgpFact.nextObject();

        return Streams.readAll(ld.getInputStream());
    }

Информация об исключении -

org.bouncycastle.openpgp.PGPException: Exception creating cipher
    at org.bouncycastle.openpgp.operator.jcajce.OperatorHelper.createDataDecryptor(Unknown Source)
    at org.bouncycastle.openpgp.operator.jcajce.JcePBEDataDecryptorFactoryBuilder$1.createDataDecryptor(Unknown Source)
    at org.bouncycastle.openpgp.PGPPBEEncryptedData.getDataStream(Unknown Source)

...
...
Caused by: java.lang.IllegalArgumentException: unknown symmetric algorithm: 112
    at org.bouncycastle.openpgp.PGPUtil.getSymmetricCipherName(Unknown Source)
    ... 21 more

Я попытался запустить Security.getAlgorithms("Cipher") , как предлагается здесь , и я не вижу CAST5 в списке возвращаемых алгоритмов.

Я нахожусь на Java 1.8 и использую библиотеки Bouncy Castle ниже

<dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bcprov-jdk15on</artifactId>
    <version>1.62</version>
    <scope>compile</scope>
</dependency>
<dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bcpg-jdk15on</artifactId>
    <version>1.62</version>
    <scope>compile</scope>
</dependency>

Любые идеи, что я должен преследовать дальше? Я также убедился, что мой код устанавливает Security.addProvider(new BouncyCastleProvider()); во время запуска.

Я чувствую, что это должно быть вопросом дополнительной поддержки JVM Ciper Suites. Но я не знаю с чего начать.

Пожалуйста, совет.


ПРИМЕЧАНИЕ: Приведенный выше код был примером из inte rnet, но, основываясь на комментариях Мартена Бодьюса, я понял, скопировав это код из inte rnet локально - я сделал много изменений, чтобы заставить его работать.

Точный код, который я использую с моей машины

public static void decryptSymmetricFile(
            InputStream in,
            char[] passwd,
            String outFileName) throws IOException {

        in = PGPUtil.getDecoderStream(in);

        PGPObjectFactory pgpF = new JcaPGPObjectFactory(in);
        PGPEncryptedDataList enc;

        Object o = pgpF.nextObject();
        if (o instanceof PGPEncryptedDataList) {
            enc = (PGPEncryptedDataList) o;
        } else {
            enc = (PGPEncryptedDataList) pgpF.nextObject();
        }

        Iterator<?> it = enc.getEncryptedDataObjects();
        PGPPBEEncryptedData      pbe = (PGPPBEEncryptedData) it.next();

        try {
            Security.getAlgorithms("Cipher");

        //****************************************
        // Hitting an exception here while doing pbe.getDataStream()... 
        // Getting  "org.bouncycastle.openpgp.PGPException: Exception creating cipher CAST5"
        //****************************************
            InputStream dataStream = pbe.getDataStream((new JcePBEDataDecryptorFactoryBuilder((new JcaPGPDigestCalculatorProviderBuilder()).setProvider("BC").build())).setProvider("BC").build(passwd));
            JcaPGPObjectFactory pgpObjectFactory = new JcaPGPObjectFactory(dataStream);
            PGPCompressedData pgpCompressedData = (PGPCompressedData) pgpObjectFactory.nextObject();
            pgpObjectFactory = new JcaPGPObjectFactory(pgpCompressedData.getDataStream());
            PGPLiteralData literalData = (PGPLiteralData) pgpObjectFactory.nextObject();

            ByteArrayOutputStream    bOut = new ByteArrayOutputStream();

            InputStream              unc = literalData.getInputStream();
            int                      ch;

            while ((ch = unc.read()) >= 0)
            {
                bOut.write(ch);
            }

            if (pbe.isIntegrityProtected() && !pbe.verify())
            {
                throw new PGPException("Data is integrity protected but integrity is lost.");
            }

            OutputStream fOut = new BufferedOutputStream(new FileOutputStream(outFileName));
            Streams.pipeAll(new ByteArrayInputStream(bOut.toByteArray()), fOut);
            fOut.close();
        } catch (Exception ex) {
            ex.printStackTrace();
            logger.error(ex.getLocalizedMessage());
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...