Very new to signing and encrypting file. Found MIMEKIT and code on stackoverflow. With little or no understanding of how the code work have made changes to it. when opening the created file in a package call p7mViewer a message The file is corrupted; Signature information might be missing. Service provider is unable to decrypt file generated suing the below code.
I need to sign with SHA-256 and encrypt using DES-3. Please see code below.
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;
}
}
}
}