Saltar al contenido

Ejemplo de descifrado de Bouncy Castle C # PGP

Solución:

Finalmente lo puse a funcionar. El principal problema que tuve con otras muestras fue el hecho de que el anillo de claves privadas que tenía incluía una clave para firmar que aparecía primero al intentar cargar la clave para descifrar. Es por eso que tuve que agregar un cheque para el ElGamalPrivateKeyParameters escriba en la clave.

A continuación se muestra mi código. No muy limpio, pero funciona.

        private static PgpPrivateKey GetPrivateKey(string privateKeyPath)
    {
        using (Stream keyIn = File.OpenRead(privateKeyPath))
        using (Stream inputStream = PgpUtilities.GetDecoderStream(keyIn))
        {
            PgpSecretKeyRingBundle secretKeyRingBundle = new PgpSecretKeyRingBundle(inputStream);

            PgpSecretKey key = null;
            foreach (PgpSecretKeyRing kRing in secretKeyRingBundle.GetKeyRings())
            {
                foreach (PgpSecretKey secretKey in kRing.GetSecretKeys())
                {
                    PgpPrivateKey privKey = secretKey.ExtractPrivateKey("1234567890".ToCharArray());

                    if (privKey.Key.GetType() ==
                        typeof (Org.BouncyCastle.Crypto.Parameters.ElGamalPrivateKeyParameters))
                        //Org.BouncyCastle.Crypto.Parameters.ElGamalPrivateKeyParameters
                    {
                        return privKey;
                    }
                }

            }
        }

        return null;
    }





    public static void Decrypt(Stream input, string outputpath, String privateKeyPath)
    {
        input = PgpUtilities.GetDecoderStream(input);
        try
        {
            PgpObjectFactory pgpObjF = new PgpObjectFactory(input);
            PgpEncryptedDataList enc;
            PgpObject obj = pgpObjF.NextPgpObject();
            if (obj is PgpEncryptedDataList)
            {
                enc = (PgpEncryptedDataList)obj;
            }
            else
            {
                enc = (PgpEncryptedDataList)pgpObjF.NextPgpObject();
            }

            var akp = new AsymmetricKeyParameter(true);



            PgpPrivateKey privKey = GetPrivateKey(privateKeyPath);


            PgpPublicKeyEncryptedData pbe = enc.GetEncryptedDataObjects().Cast<PgpPublicKeyEncryptedData>().First();
            Stream clear;
            clear = pbe.GetDataStream(privKey);
            PgpObjectFactory plainFact = new PgpObjectFactory(clear);
            PgpObject message = plainFact.NextPgpObject();
            if (message is PgpCompressedData)
            {
                PgpCompressedData cData = (PgpCompressedData)message;
                Stream compDataIn = cData.GetDataStream();
                PgpObjectFactory o = new PgpObjectFactory(compDataIn);
                message = o.NextPgpObject();
                if (message is PgpOnePassSignatureList)
                {
                    message = o.NextPgpObject();
                    PgpLiteralData Ld = null;
                    Ld = (PgpLiteralData)message;
                    Stream output = File.Create(outputpath + "\" + Ld.FileName);
                    Stream unc = Ld.GetInputStream();
                    Streams.PipeAll(unc, output);
                }
                else
                {
                    PgpLiteralData Ld = null;
                    Ld = (PgpLiteralData)message;
                    //Stream output = File.Create(outputpath + "\" + Ld.FileName);
                    Stream output = File.Create(outputpath);
                    Stream unc = Ld.GetInputStream();
                    Streams.PipeAll(unc, output);
                }
            }
        }
        catch (Exception e)
        {
            throw new Exception(e.Message);
        }
    }

Estaba teniendo problemas con la función Decrypt de Ron Harlev que retiene el archivo de salida hasta que se termina el programa. Agregué algunas declaraciones de uso en torno a Stream para superar este problema. También reemplacé la frase de contraseña codificada a favor de un argumento de entrada. Espero que alguien lo encuentre útil.

private static bool DecryptFile(Stream inputStream, string outputDir, char[] passPhrase, string privateKeyLoc)
    {
        try
        {
            using (var newStream = PgpUtilities.GetDecoderStream(inputStream))
            {
                PgpObjectFactory pgpObjF = new PgpObjectFactory(newStream);
                PgpEncryptedDataList enc;
                PgpObject obj = pgpObjF.NextPgpObject();
                if (obj is PgpEncryptedDataList)
                {
                    enc = (PgpEncryptedDataList)obj;
                }
                else
                {
                    enc = (PgpEncryptedDataList)pgpObjF.NextPgpObject();
                }

                var akp = new AsymmetricKeyParameter(true);
                PgpPrivateKey privKey = GetPrivateKey(privateKeyLoc, passPhrase, logger);

                PgpPublicKeyEncryptedData pbe = enc.GetEncryptedDataObjects().Cast<PgpPublicKeyEncryptedData>().First();

                using (Stream clear = pbe.GetDataStream(privKey))
                {
                    PgpObjectFactory plainFact = new PgpObjectFactory(clear);
                    PgpObject message = plainFact.NextPgpObject();

                    if (message is PgpCompressedData)
                    {
                        PgpCompressedData cData = (PgpCompressedData)message;
                        Stream compDataIn = cData.GetDataStream();
                        PgpObjectFactory o = new PgpObjectFactory(compDataIn);
                        message = o.NextPgpObject();
                        if (message is PgpOnePassSignatureList)
                        {
                            message = o.NextPgpObject();
                        }
                        PgpLiteralData Ld = null;
                        Ld = (PgpLiteralData)message;
                        using (Stream output = File.Create(outputDir + "\" + Ld.FileName))
                        {
                            Stream unc = Ld.GetInputStream();
                            Streams.PipeAll(unc, output);
                        }
                    }
                }
            }

            return true;
        }
        catch (Exception e)
        {
            throw new Exception(e.Message);
            return false;
        }
    }
¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *