Search code examples
c#bouncycastlepkcs#7pkcs#12

how to encrypt zip file with p7b certificate and sign it with p12


I have a p7b file which includes the public key the goal is to encrypted a zip file with this public key and change the file to .zip.encrypted and then use a .p12 file to sign the content

Questions

Right now I'm trying to figure out how this works. Is this just pkcs#7 encryption or do I call it CMS Evelope? Since in the p7b file i only have a public rsa key how would I be able to encrypt a whole zip file with it? As far as I know you can only encrypt small bytes with RSA encryption. Is there somekind of bytestream that I can use to encrypt every single byte of a zip file by it self? Or do I generate somehow a AES key out of the public RSA key from the p7b file? Do I need to add the p7b certificate to my windows account to get access to the data inside?

What I've tried

I tried the .net recources and couldn't figure out how to get what I want, then I googled a lot found many examples how people encrypt a short string and tried to adapt but it was never working for me.

Now I'm using Bouncy Castle for c# and I think I was able to read the public key from my p7b file when I try to encrypt a normal short string, it seems to work. But when I use my zip file then I get an exception that my byte array is too big. The zip file I use for this test is only 3KB, the real files later will be up to ~200MB

So I guess the Way im using the p7b file aswell as bouncy castle for my problem is wrong.

My Code

 var p7bFilePath = @"key\Test.p7b";
 var text = @"zipfile";
 var bytesToEncrypt = File.ReadAllBytes(@"zip\test.zip");
 var certi = ReadCertificate(p7bFilePath);
 var encodedPublicKey = certi.GetPublicKey();
 var encryptEngine = new Pkcs1Encoding(new RsaEngine());
 encryptEngine.Init(true, encodedPublicKey);
 var encrypted = Convert.ToBase64String(encryptEngine.ProcessBlock(bytesToEncrypt, 0, bytesToEncrypt.Length));

 Console.WriteLine(encrypted);

Solution

  • Okay since I asked this question before just deleted it and rewrote it a little with the hope somebody might help me. I think I came to the solution with the help of a collegue:

    using Org.BouncyCastle.Asn1;
    using Org.BouncyCastle.Cms;
    using Org.BouncyCastle.Pkcs;
    using Org.BouncyCastle.X509;
    using System.IO;
    
    namespace pkchwencrypting
    {
        class Program
        {
            static void Main(string[] args)
            {
                var certificateData = File.ReadAllBytes("YOUR_p7b_FILE");
                var cert = new X509CertificateParser().ReadCertificate(certificateData);
                //I just wanted to know if I can see the publicKey somehow            
                //var publicKey = cert.GetPublicKey();
    
                var store = new Pkcs12Store(File.OpenRead("YOUR_p12_File"), "test".ToCharArray());
                var privateKey = store.GetKey("THE_NAME_OF_KEY_YOU_WANT_TO_GET").Key;
    
                var signedDataGen = new CmsSignedDataGenerator();
                signedDataGen.AddSigner(privateKey, cert, CmsSignedDataGenerator.EncryptionRsa, CmsSignedDataGenerator.DigestSha512);
    
                var zipContent = new CmsProcessableFile(new FileInfo("YOUR_DATA_FILE"));
                //For me a zip
                var signedData = signedDataGen.Generate(zipContent, true);
    
                var envDataGen = new CmsEnvelopedDataGenerator();
                envDataGen.AddKeyTransRecipient(cert);
    
                var sData = new CmsProcessableByteArray(signedData.GetEncoded());
                var enveloped = envDataGen.Generate(sData, CmsEnvelopedDataGenerator.DesEde3Cbc);
    
                var dos = new DerOutputStream(File.OpenWrite("YOUR_DATA_FILE.zip.encrypted.sig)"));
                var bytesToWrite = enveloped.GetEncoded();
                dos.Write(bytesToWrite, 0, bytesToWrite.Length);
                dos.Flush();
                dos.Close();
            }
        }
    }
    

    This might help somebody, maybe somebody can have a look at it, if this actually makes sense but it seems to do what it supposed to do.