2011-08-08 345 views
8

He visto una cantidad de publicaciones, seguí una serie de tutoriales pero ninguno parece funcionar. A veces, hacen referencia a algunas clases que no se encuentran. ¿Se me puede indicar un lugar donde pueda obtener un tutorial sencillo que muestre cómo cifrar y descifrar un archivo?Encriptación y descifrado de PgP usando BouncyCastle C#

Soy muy nuevo en Pgp y cualquier ayuda es bienvenida.

Respuesta

3

¿Cómo es esto:

PartialInputStream during Bouncycastle PGP decryption

Además, el zip contiene ejemplos aquí:

http://www.bouncycastle.org/csharp/

Espero que esto ayude. Si aún está atascado, publique más detalles sobre las clases de las que se queja el compilador y la comunidad las verá.

+0

Hola. Creo que escribiré una solución completa y publicaré mi código con los errores que pueda obtener. Verificará el código de descifrado. – ritcoder

+3

Encontré un ejemplo en [link] (http://blogs.microsoft.co.il/blogs/kim/archive/2009/01/23/pgp-zip-encrypted-files-with-c.aspx). Tiene encriptar y descifrar. Gracias – ritcoder

21

Sé que esta pregunta tiene años pero todavía es la número 1 o la número 2 en Google para búsquedas relacionadas con el descifrado de PGP utilizando Bouncy Castle. Dado que parece difícil encontrar un ejemplo completo y sucinto, quería compartir mi solución de trabajo aquí para descifrar un archivo PGP. Esto es simplemente una versión modificada del ejemplo de Bouncy Castle incluido con sus archivos fuente.

using System; 
using System.IO; 
using Org.BouncyCastle.Bcpg.OpenPgp; 
using Org.BouncyCastle.Utilities.IO; 

namespace PGPDecrypt 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      DecryptFile(
       @"path_to_encrypted_file.pgp", 
       @"path_to_secret_key.asc", 
       "your_password_here".ToCharArray(), 
       "output.txt" 
      ); 
     } 

     private static void DecryptFile(
      string inputFileName, 
      string keyFileName, 
      char[] passwd, 
      string defaultFileName) 
     { 
      using (Stream input = File.OpenRead(inputFileName), 
        keyIn = File.OpenRead(keyFileName)) 
      { 
       DecryptFile(input, keyIn, passwd, defaultFileName); 
      } 
     } 

     private static void DecryptFile(
      Stream inputStream, 
      Stream keyIn, 
      char[] passwd, 
      string defaultFileName) 
     { 
      inputStream = PgpUtilities.GetDecoderStream(inputStream); 

      try 
      { 
       PgpObjectFactory pgpF = new PgpObjectFactory(inputStream); 
       PgpEncryptedDataList enc; 

       PgpObject o = pgpF.NextPgpObject(); 
       // 
       // the first object might be a PGP marker packet. 
       // 
       if (o is PgpEncryptedDataList) 
       { 
        enc = (PgpEncryptedDataList)o; 
       } 
       else 
       { 
        enc = (PgpEncryptedDataList)pgpF.NextPgpObject(); 
       } 

       // 
       // find the secret key 
       // 
       PgpPrivateKey sKey = null; 
       PgpPublicKeyEncryptedData pbe = null; 
       PgpSecretKeyRingBundle pgpSec = new PgpSecretKeyRingBundle(
        PgpUtilities.GetDecoderStream(keyIn)); 

       foreach (PgpPublicKeyEncryptedData pked in enc.GetEncryptedDataObjects()) 
       { 
        sKey = FindSecretKey(pgpSec, pked.KeyId, passwd); 

        if (sKey != null) 
        { 
         pbe = pked; 
         break; 
        } 
       } 

       if (sKey == null) 
       { 
        throw new ArgumentException("secret key for message not found."); 
       } 

       Stream clear = pbe.GetDataStream(sKey); 

       PgpObjectFactory plainFact = new PgpObjectFactory(clear); 

       PgpObject message = plainFact.NextPgpObject(); 

       if (message is PgpCompressedData) 
       { 
        PgpCompressedData cData = (PgpCompressedData)message; 
        PgpObjectFactory pgpFact = new PgpObjectFactory(cData.GetDataStream()); 

        message = pgpFact.NextPgpObject(); 
       } 

       if (message is PgpLiteralData) 
       { 
        PgpLiteralData ld = (PgpLiteralData)message; 

        string outFileName = ld.FileName; 
        if (outFileName.Length == 0) 
        { 
         outFileName = defaultFileName; 
        } 

        Stream fOut = File.Create(outFileName); 
        Stream unc = ld.GetInputStream(); 
        Streams.PipeAll(unc, fOut); 
        fOut.Close(); 
       } 
       else if (message is PgpOnePassSignatureList) 
       { 
        throw new PgpException("encrypted message contains a signed message - not literal data."); 
       } 
       else 
       { 
        throw new PgpException("message is not a simple encrypted file - type unknown."); 
       } 

       if (pbe.IsIntegrityProtected()) 
       { 
        if (!pbe.Verify()) 
        { 
         Console.Error.WriteLine("message failed integrity check"); 
        } 
        else 
        { 
         Console.Error.WriteLine("message integrity check passed"); 
        } 
       } 
       else 
       { 
        Console.Error.WriteLine("no message integrity check"); 
       } 
      } 
      catch (PgpException e) 
      { 
       Console.Error.WriteLine(e); 

       Exception underlyingException = e.InnerException; 
       if (underlyingException != null) 
       { 
        Console.Error.WriteLine(underlyingException.Message); 
        Console.Error.WriteLine(underlyingException.StackTrace); 
       } 
      } 
     } 

     private static PgpPrivateKey FindSecretKey(PgpSecretKeyRingBundle pgpSec, long keyID, char[] pass) 
     { 
      PgpSecretKey pgpSecKey = pgpSec.GetSecretKey(keyID); 

      if (pgpSecKey == null) 
      { 
       return null; 
      } 

      return pgpSecKey.ExtractPrivateKey(pass); 
     } 
    } 
} 
+1

No es exactamente lo que necesitaba, pero lo suficientemente cerca como para adaptarlo a mis necesidades. Me ahorró una buena cantidad de trabajo. Bouncy Castle sigue siendo la mejor solución gratuita que he encontrado para PGP en .NET, y supera a algunos pagos también. – dave

+0

¿sabes cómo resolver "el mensaje cifrado contiene un mensaje firmado, no datos literales". error? –

+0

@MokhAkh, si miras mi código, verás que este error se produce cuando el mensaje es PgpOnePassSignatureList en lugar del PgpLiteralData esperado. No conozco su escenario exacto, pero supongo que si comienza a buscar SO o Google para PgpOnePassSignatureList, comenzará a resolverlo. – Dan

Cuestiones relacionadas