bcgit/bc-csharp

Issue decrypting with Kleopatra encrypted file created with BouncyCastle for .Net

boggye opened this issue · 0 comments

Hello,

I encrypted a file using a .Net 8.0 F# program that references BouncyCastle.Cryptography version 2.4.0. When I try to decrypt it using Kleopatra, I get these messages:

gpg: encrypted with rsa4096 key, ID 201748...., created 2019-04-15
      "..."
gpg: used key is not marked for encryption use.
gpg: WARNING: cipher algorithm CAST5 not found in recipient preferences
gpg: zlib inflate problem: invalid block type

Here are the version numbers:
Kleopatra: 3.2.2.2311170 (Gpg4win-4.3.1)

GnuPG 2.4.5
Libgcrypt 1.10.3

Here is the source code of the F# program:

open System
open System.IO

open System.Text
open Org.BouncyCastle.Bcpg
open Org.BouncyCastle.Bcpg.OpenPgp
open Org.BouncyCastle.Security
    
let readPublicKeyFromStream (input: Stream): PgpPublicKey =    
    let stream2 = PgpUtilities.GetDecoderStream(input)
    let pgpPub =  PgpPublicKeyRingBundle(stream2)
    let key = pgpPub.GetKeyRings() |> Seq.collect (fun kr -> kr.GetPublicKeys()) |> Seq.tryFind (fun k -> k.IsEncryptionKey)
    if key.IsSome then
        key.Value
    else
        failwith "Unable to find a public key in the stream"    


let readPublicKeyFromString (publicKey: string) =
  use stream = new MemoryStream(Encoding.UTF8.GetBytes(publicKey))
  readPublicKeyFromStream stream
  
let readPublicKeyFromFile (fileName: string) =
    let publicKey = File.ReadAllText(fileName, Encoding.UTF8)
    readPublicKeyFromString publicKey
    
let compressFile (algorithm: CompressionAlgorithmTag) (inputFileName: string): string =     
    let outputFileName = Path.GetTempFileName()
    //use fsout = File.Create(outputFileName)
    use fsout = new MemoryStream()
    let inputFileInfo = FileInfo(inputFileName)
    // use fsinput = File.OpenRead(inputFileName)
    let inputContent = File.ReadAllBytes(inputFileName)
    let comData = PgpCompressedDataGenerator(algorithm)
    use pOut = PgpLiteralDataGenerator().Open(comData.Open(fsout), PgpLiteralData.Binary, inputFileName, inputContent.Length, DateTime.Now)    
    //fsinput.CopyTo(pOut)
    pOut.Write(inputContent, 0, inputContent.Length)
    pOut.Flush()
    pOut.Close()
    fsout.Flush()
    File.WriteAllBytes(outputFileName, fsout.ToArray())
    outputFileName

    
let encryptFile (inputFileName: string) (outputFileName: string)  (encKeyFileName: string) (withIntegrityCheck: bool) =
  let encKey = readPublicKeyFromFile encKeyFileName
  use fsout = File.Create(outputFileName)
  use outputStream = new ArmoredOutputStream(fsout)  
  let compressedFileName = compressFile CompressionAlgorithmTag.Zip inputFileName
  let encGen = new PgpEncryptedDataGenerator(SymmetricKeyAlgorithmTag.Cast5, withIntegrityCheck, new SecureRandom())
  encGen.AddMethod(encKey)
  let content = File.ReadAllBytes(compressedFileName)
  let compressedFileNameInfo = FileInfo(compressedFileName)
  let cOut = encGen.Open(outputStream, content.Length )
  //use compressedFileStream = File.OpenRead(compressedFileName)
  //compressedFileStream.CopyTo(cOut)
  cOut.Write(content, 0, content.Length)
  cOut.Close()
  outputFileName

I should also mention the file is decrypted successfully using another BC custom program which is great!

Any ideas? I tried to decrypt the file using the gnugpg command line but it returns the same message as above.

I know this is a question about another tool, but if you have any insight it would be great if you can share it. While it is not a requirement that the file should be decrypted using Kleopatra, it is useful to be able to do so for testing purposes.

Thank you

Edit: I also found this thread: https://forum.gnupg.org/t/zlib-inflate-problem-invalid-block-typ/3551

Edit2: Using CompressionAlgorithmTag.BZip2 instead of CompressionAlgorithmTag.Zip seems to work, i.e. the file is decrypted successfully by Kleopatra.