Подписать и зашифровать простой текстовый файл с цифровым сертификатом, используя MIMEKIT - PullRequest
0 голосов
/ 16 октября 2018

Очень плохо знаком с подписью и шифрованием файла.Нашел MIMEKIT и код на стеке потока.Почти или совсем не понимая, как работает код, в него были внесены изменения.при открытии созданного файла в пакете вызывается p7mViewer сообщение Файл поврежден;Информация о подписи может отсутствовать.Поставщик услуг не может расшифровать сгенерированный файл, используя приведенный ниже код.

Мне нужно подписать с SHA-256 и зашифровать с использованием DES-3.Пожалуйста, смотрите код ниже.

using System;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Windows.Forms;
using Org.BouncyCastle.Cms;
using Org.BouncyCastle.Pkcs;
using Org.BouncyCastle.X509;
using MimeKit;
using System.Text;

namespace ConsoleApplicationSignWithBouncyCastle
{
class Program
{

    [STAThread]
    static void Main(string[] args)
    {

        try
        {
            // First load a Certificate, filename/path and certificate password
            Cert = ReadCertFromFile("c:/temp1/cert.pfx", "password");

            //  Select a binary file
            var dialog = new OpenFileDialog
            {
                Filter = "All files (*.*)|*.*",
                InitialDirectory = "./",
                Title = "Select a text file"
            };
            var filename = (dialog.ShowDialog() == DialogResult.OK) ? dialog.FileName : null;

            // Get the file
          byte[] fileContent = File.ReadAllBytes( filename);

            // Create the generator
            var dataGenerator = new CmsEnvelopedDataStreamGenerator();

            // Add receiver
            // Cert is the user's X.509 Certificate set bellow
             dataGenerator.AddKeyTransRecipient(Cert);

            // Make the output stream 
            int startFileName = filename.LastIndexOf(@"\") +1;
            string outFile = @"c:\temp1\"+ filename.Substring(startFileName, filename.LastIndexOf(".") - startFileName) + "_w_2.edi";
            var outStream = new FileStream(outFile, FileMode.Create);

            string Streamline = "";
            byte[] StreamBytes = null;
            byte[] newline = Encoding.ASCII.GetBytes(Environment.NewLine);

            Streamline = "MIME-Version: 1.0";
            StreamBytes = Encoding.ASCII.GetBytes(Streamline);
            outStream.Write(StreamBytes , 0,Streamline.Length  );
            outStream.Write(newline, 0, newline.Length );

            Streamline = "Date: " + DateTime.Now.ToString("ddd, dd MMM yyyy HH:mm:ss") + " +0000";
            StreamBytes = Encoding.ASCII.GetBytes(Streamline);
            outStream.Write(StreamBytes, 0, Streamline.Length);
            outStream.Write(newline, 0, newline.Length);

            Streamline = "X-Priority: 3 (Normal)";
            StreamBytes = Encoding.ASCII.GetBytes(Streamline);
            outStream.Write(StreamBytes, 0, Streamline.Length);
            outStream.Write(newline, 0, newline.Length);

            Streamline = "Message-ID: <10000003141>";
            StreamBytes = Encoding.ASCII.GetBytes(Streamline);
            outStream.Write(StreamBytes, 0, Streamline.Length);
            outStream.Write(newline, 0, newline.Length);

            Streamline = "Content-Disposition: attachment; filename="+@"""smime.p7m""";
            StreamBytes = Encoding.ASCII.GetBytes(Streamline);
            outStream.Write(StreamBytes, 0, Streamline.Length);
            outStream.Write(newline, 0, newline.Length);

            Streamline = "Content-Transfer-Encoding: binary";
            StreamBytes = Encoding.ASCII.GetBytes(Streamline);
            outStream.Write(StreamBytes, 0, Streamline.Length);
            outStream.Write(newline, 0, newline.Length);

            Streamline = "AS3-From: PILM";
            StreamBytes = Encoding.ASCII.GetBytes(Streamline);
            outStream.Write(StreamBytes, 0, Streamline.Length);
            outStream.Write(newline, 0, newline.Length);

            Streamline = "AS3-To: SARS";
            StreamBytes = Encoding.ASCII.GetBytes(Streamline);
            outStream.Write(StreamBytes, 0, Streamline.Length);
            outStream.Write(newline, 0, newline.Length);

            Streamline = "Subject: "+ filename.Substring(startFileName, filename.LastIndexOf(".") - startFileName) ;
            StreamBytes = Encoding.ASCII.GetBytes(Streamline);
            outStream.Write(StreamBytes, 0, Streamline.Length);
            outStream.Write(newline, 0, newline.Length);

            Streamline = "Content-Type: application/pkcs7-mime; smime-type="+@"""enveloped - data"""+ ";name="+@"""smime.p7m""";
            StreamBytes = Encoding.ASCII.GetBytes(Streamline);
            outStream.Write(StreamBytes, 0, Streamline.Length);
            outStream.Write(newline, 0, newline.Length);
            outStream.Write(newline, 0, newline.Length);

            // Sign the stream
            var cryptoStream = dataGenerator.Open(outStream, CmsEnvelopedGenerator.DesEde3Cbc  );
            // Store in our binary stream writer and write the signed content
            var binWriter = new BinaryWriter(cryptoStream);
            binWriter.Write(fileContent);



        }
        catch (Exception ex)
        {
            Console.WriteLine("So, you wanna make an exception huh! : " + ex.ToString());
            Console.ReadKey();
        }
    }

    public static Org.BouncyCastle.X509.X509Certificate Cert { get; set; }

    // This reads a certificate from a file.
    // Thanks to: http://blog.softwarecodehelp.com/2009/06/23/CodeForRetrievePublicKeyFromCertificateAndEncryptUsingCertificatePublicKeyForBothJavaC.aspx
    public static Org.BouncyCastle.X509.X509Certificate ReadCertFromFile(string strCertificatePath, string strCertificatePassword)
    {
        try
        {

            X509Certificate2 myCert =  new X509Certificate2(strCertificatePath, strCertificatePassword);
            var cert = Org.BouncyCastle.Security.DotNetUtilities.FromX509Certificate(myCert);

            return cert;
        }
        catch (Exception ex)
        {
            Console.WriteLine("So, you wanna make an exception huh! : " + ex.ToString());
            Console.ReadKey();
            return null;
        }
    }


}

}

1 Ответ

0 голосов
/ 17 октября 2018

Если вы использовали MimeKit вместо того, чтобы пытаться сгенерировать свой собственный MIME вручную, вы можете сделать что-то вроде этого:

using System;
using System.IO;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Windows.Forms;

using MimeKit;
using MimeKit.Cryptography;

namespace ConsoleApplicationSignWithBouncyCastle
{
    class Program
    {
        [STAThread]
        static void Main (string[] args)
        {
            //  Select a binary file
            var dialog = new OpenFileDialog {
                Filter = "All files (*.*)|*.*",
                InitialDirectory = "./",
                Title = "Select a text file"
            };
            var filename = (dialog.ShowDialog () == DialogResult.OK) ? dialog.FileName : null;
            var certificate2 = new X509Certificate2 ("c:/temp1/cert.pfx", "password");
            MimeEntity body;

            using (var content = new MemoryStream (File.ReadAllBytes (filename)))
                var part = new MimePart (MimeTypes.GetMimeType (filename)) {
                    ContentDisposition = new ContentDisposition (ContentDisposition.Attachment),
                    ContentTransferEncoding = ContentEncoding.Binary,
                    FileName = Path.GetFileName (filename),
                    Content = new MimeContent (content)
                };

                var recipient = new CmsRecipient (certificate2) {
                    EncryptionAlgorithms = new EncryptionAlgorithm[] { EncryptionAlgorithm.TripleDes }
                };
                var recipients = new CmsRecipientCollection ();
                recipients.Add (recipient);

                using (var ctx = new TemporarySecureMimeContext ())
                    body = ApplicationPkcs7Mime.Encrypt (ctx, recipients, part);
            }

            var message = new MimeMessage ();
            message.Headers.Add ("AS3-From", "PILM");
            message.Headers.Add ("AS3-To", "SARS");
            message.Subject = Path.GetFileNameWithoutExtension (filename);
            message.Date = DateTimeOffset.Now;
            message.MessageId = "10000003141";
            message.Body = body;

            var outFile = @"c:\temp1\" + Path.GetFileNameWithoutExtension (filename) + "_w_2.edi";
            message.WriteTo (outFile);
        }
    }
}

Обратите внимание, насколько проще приведенный выше фрагмент кода, чем ваш исходный фрагмент кода.Разница между днем ​​и ночью:)

Если вы также хотите подписать, используя SHA-256, вы можете сделать это вместо этого (очень незначительные различия):

using System;
using System.IO;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Windows.Forms;

using MimeKit;
using MimeKit.Cryptography;

namespace ConsoleApplicationSignWithBouncyCastle
{
    class Program
    {
        [STAThread]
        static void Main (string[] args)
        {
            //  Select a binary file
            var dialog = new OpenFileDialog {
                Filter = "All files (*.*)|*.*",
                InitialDirectory = "./",
                Title = "Select a text file"
            };
            var filename = (dialog.ShowDialog () == DialogResult.OK) ? dialog.FileName : null;
            var certificate2 = new X509Certificate2 ("c:/temp1/cert.pfx", "password");
            MimeEntity body;

            using (var content = new MemoryStream (File.ReadAllBytes (filename)))
                var part = new MimePart (MimeTypes.GetMimeType (filename)) {
                    ContentDisposition = new ContentDisposition (ContentDisposition.Attachment),
                    ContentTransferEncoding = ContentEncoding.Binary,
                    FileName = Path.GetFileName (filename),
                    Content = new MimeContent (content)
                };

                var recipient = new CmsRecipient (certificate2) {
                    EncryptionAlgorithms = new EncryptionAlgorithm[] { EncryptionAlgorithm.TripleDes }
                };
                var recipients = new CmsRecipientCollection ();
                recipients.Add (recipient);

                var signer = new CmsSigner (certificate2) {
                    DigestAlgorithm = DigestAlgorithm.Sha256
                };

                using (var ctx = new TemporarySecureMimeContext ()) {
                    using (var stream = File.OpenRead ("c:/temp1/cert.pfx"))
                        ctx.Import (stream, "password");
                    body = ApplicationPkcs7Mime.SignAndEncrypt (ctx, signer, recipients, part);
                }
            }

            var message = new MimeMessage ();
            message.Headers.Add ("AS3-From", "PILM");
            message.Headers.Add ("AS3-To", "SARS");
            message.Subject = Path.GetFileNameWithoutExtension (filename);
            message.Date = DateTimeOffset.Now;
            message.MessageId = "10000003141";
            message.Body = body;

            var outFile = @"c:\temp1\" + Path.GetFileNameWithoutExtension (filename) + "_w_2.edi";
            message.WriteTo (outFile);
        }
    }
}
...