Geeks With Blogs

News Awarded Microsoft MVP C#.NET - 2007, 2008 and 2009


I am born in Bangladesh and currently live in Melbourne, Australia. I am a Microsoft Certified Application Developer MCAD Chartered Member (C# .Net)and born in Bangladesh.
I am founder and Chief Executive Officer of
Simplexhub, a highly experienced software development company based in Melbourne Australia and Dhaka, Bangladesh. Co-founder and core developer of Pageflakes www.pageflakes.com.
Simplexhub, is on its mission to build a smart virtual community in Bangladesh and recently launched beta realestatebazaar.com.bd an ASP.NET MVC application written in C#.NET.


Some of My Articles
Flexible and Plugin based .Net Application..
Mass Emailing Functionality with C#, .NET 2.0, and Microsoft® SQL Server 2005 Service Broker'
Write your own Code Generator or Template Engine in .NET

Shahed Khan blog

I am playing with .Net2.0 Cryptography,  and want to Implement different scenarios. Let me start with this one and please comment if you know of a better solution.

Scenario 1: I want to setup a Public Key Interface, where Sender signs a Message using Senders Certificate and then Encrypts / Envelops it using Recipients Certificate and then Send the Encrypted Message.

Solution: I am writing a Sender WebApplication where on click of a Button, Recipients Certificate is downloaded from a WebService Store and then signed and encrypted and sent to the Webservice. The Webservice then saves the encrypted Message in the c:\temp folder.

I ll be using the new X509Certificate2 that ships with .Net2.0.

Step 1 : I created 2 Certificate one for Recipient and one for Sender using the makecert tool.

C:\Program Files\Microsoft Visual Studio 8\VC>makecert -n "CN=SmartCryptoGraphy

Recipient1" -ss My

Succeeded


C:\Program Files\Microsoft Visual Studio 8\VC>makecert -n "CN=SmartCryptoGraphy

Signer1" -ss My

Succeeded

for more details on the Certificate Creation Tool please refer to this link.
http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/sag_cmprocsimport.mspx?mfr=true

Step 2: Create a WebService with the implementation of 2 Methods:

[WebMethod]
public byte[] GetRecipientCertificateFromStore(string recipientName)
{
}

[WebMethod]
public bool SendMessage(string message)
{
}

 

GetRecipientCertificateFromStore will return Recipients Certificate from My store. Here is the Implementation.

	
	[WebMethod]
        public byte[] GetRecipientCertificateFromStore(string recipientName)
        {
            //Do the searching of Certificate and send it back
            X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
            store.Open(OpenFlags.ReadOnly);
                       
            X509Certificate2Collection certColl =
                store.Certificates.Find(X509FindType.FindBySubjectName,
                recipientName, false);            
            if (certColl.Count == 0)
            {
                store.Close();
                return null;
            }   
            store.Close();
            return certColl[0].Export(X509ContentType.Cert);
        }


The code is self explanatory it instantiates a X509Store object pointing to StoreName.My where I have previously saved the Certificates. Then it searches the store by the recipientName using the store.Certificates.Find method, and when it finds the desired certificate, returns byte[] using the X509Certificate2.Export Method.

 

SendMessage will recive encrypted message and simply store it to c:\temp folder. Here is the implementation:

	[WebMethod]
        public bool SendMessage(string message)
        {
            Guid id = Guid.NewGuid();
            try
            {
                using (System.IO.StreamWriter sw = System.IO.File.CreateText(string.Format(@"C:\temp\message_{0}.txt",id.ToString())))
                {
                    sw.Write(message);
                }
            }
            catch
            {
                return false;
            }
	
            return true;
        }


The above code is self explanatory.

Step 3: Creating the Sender WebApplication

I chosen a WebApplication for Sender as in future Scenarios I want to implement SSL, RequestClientCertificate etc.
Now the WebService can be communicated via any client but in future scenarios I want to restrict that communication too and want to implement autorized clients access to the webservice using SSL and Certificates...

Anyways now its simple and the future scenarios will be more complicated....Now I created I WebPage with 2 TextBox and a Send Button.

<form id="form1" runat="server">
<div>
Recipient Name<br />
<asp:TextBox ID="tbRecipientName" runat="server"></asp:TextBox><br />
Enter Message<br />
<asp:TextBox ID="tbMessage" runat="server" Height="88px" TextMode="MultiLine"></asp:TextBox><br />
<asp:Button ID="btnSend" runat="server" OnClick="btnSend_Click" Text="Send" /><br />
<asp:Label ID="lblReport" runat="server"></asp:Label></div>
</form>

On Button Click the web application loads the Signers Certificate then contacts the previously created webservice and requests the Recipient Certificate......by the RecipientName entered in the textbox.


After getting both Certificates it signs the message entered in the textbox, and then encrypts and envelops it using the Recipients Certificate and then Sends to the WebService.....The source code looks like this. 

        protected void btnSend_Click(object sender, EventArgs e)
        {
            //Get Signer Certificate
            X509Certificate2 signerCertificate = GetSignerCert();
            if (signerCertificate == null)
                return;
            //Get Recipient Certificate
            GetRecipientCert();
            if (recipientCertificate == null)
            {
                lblReport.Text ="Recipient Certificate to use for this application could not be found.";
                return;
            }
            //Sign the Message
            Encoding unicode = Encoding.Unicode;
            byte[] msgBytes = unicode.GetBytes(tbMessage.Text);
            byte[] encodedSignedCms = SignMesage(msgBytes, signerCertificate);
            //Encrypt the Message
            //  Encrypt the encoded SignedCms message.
            byte[] encodedEnvelopedCms = EncryptMsg(encodedSignedCms,
                recipientCertificate);            
            //Send
            string encryptedMessage = Convert.ToBase64String(encodedEnvelopedCms);
            Send(encryptedMessage);
        }
        
        public X509Certificate2 GetSignerCert()
        {
            //  Open the My certificate store.
            X509Store storeMy = new X509Store(StoreName.My,
                StoreLocation.CurrentUser);
            storeMy.Open(OpenFlags.ReadOnly);
           
            X509Certificate2Collection certColl =
                storeMy.Certificates.Find(X509FindType.FindBySubjectName,
                signerName, false);           

            if (certColl.Count == 0)
            {
                lblReport.Text ="Signer Certificate to use for this application could not be found in the certificate store. Please check the SignerName in Web.config for signing the message.";
                storeMy.Close();
                return null;
            }
            storeMy.Close();
            return certColl[0];
        }

        X509Certificate2 recipientCertificate = null;
        public void GetRecipientCert()
        {
            SmartCryptoGraphyService service = new SmartCryptoGraphyService();            
            byte[] recipientCertificateByte = service.GetRecipientCertificateFromStore(tbRecipientName.Text);            
            X509Certificate2 cert = new X509Certificate2(recipientCertificateByte);
            recipientCertificate = cert;
        }        

        public byte[] SignMesage( Byte[] message, X509Certificate2 signerCert)
        {
            //  Place message in a ContentInfo object.
            //  This is required to build a SignedCms object.
            ContentInfo contentInfo = new ContentInfo(message);

            //  Instantiate SignedCms object with the ContentInfo above.
            //  Has default SubjectIdentifierType IssuerAndSerialNumber.
            //  Has default Detached property value false, so message is
            //  included in the encoded SignedCms.
            SignedCms signedCms = new SignedCms(contentInfo);

            //  Formulate a CmsSigner object, which has all the needed
            //  characteristics of the signer.
            CmsSigner cmsSigner = new CmsSigner(signerCert);

            //  Sign the PKCS #7 message.
            signedCms.ComputeSignature(cmsSigner);
            //  Encode the PKCS #7 message.
            return signedCms.Encode();
        }

        public byte[] EncryptMsg(Byte[] message, X509Certificate2 recipientCert)
        {
            //  Place message in a ContentInfo object.
            //  This is required to build an EnvelopedCms object.
            ContentInfo contentInfo = new ContentInfo(message);

            //  Instantiate EnvelopedCms object with the ContentInfo
            //  above.
            //  Has default SubjectIdentifierType IssuerAndSerialNumber.
            //  Has default ContentEncryptionAlgorithm property value
            //  RSA_DES_EDE3_CBC.
            EnvelopedCms envelopedCms = new EnvelopedCms(contentInfo);

            //  Formulate a CmsRecipient object that
            //  represents information about the recipient
            //  to encrypt the message for.
            CmsRecipient recip1 = new CmsRecipient(
                SubjectIdentifierType.IssuerAndSerialNumber,
                recipientCert);                      

            //  Encrypt the message for the recipient.
            envelopedCms.Encrypt(recip1);            

            //  The encoded EnvelopedCms message contains the encrypted
            //  message and the information about each recipient that
            //  the message was enveloped for.
            return envelopedCms.Encode();
        }

        private void Send(string message)
        {
            SmartCryptoGraphyService service = new SmartCryptoGraphyService();
            service.SendMessageCompleted +=new SendMessageCompletedEventHandler(service_SendMessageCompleted);
            service.SendMessageAsync(message);

        }

        void service_SendMessageCompleted(object sender, SendMessageCompletedEventArgs e)
        {
            if (e.Result)
            {
                lblReport.Text = "Message Sent Successfully";
            }
            else
            {
                lblReport.Text = "Message sending failed";
            }
        }
The above code is self explanatory but you can study a bit more about these
classes in MSDN.... ContentInfo, SignedCms, CmsSigner, EnvelopedCms, CmsRecipient.
Note the signedCms.ComputeSignature(cmsSigner); 
The CheckSignature(Boolean) method verifies the digital signatures on the signed CMS/PKCS #7 message and, optionally, validates the signers' certificates.

Also Note the signedCms.Encode(); The Encode method encodes the information in the object into a CMS/PKCS #7 message.

Also Note the envelopedCms.Encrypt(recip1);
The message is encrypted by using a message encryption key with a symmetric encryption algorithm such as triple DES.
The message encryption key is then encrypted with the public key of each recipient.

The application worked ok for me as a demonstration of example
and generated encrypted messages...here is an example message

MIID7gYJKoZIhvcNAQcDoIID3zCCA9sCAQAxgcQwgcECAQAwKj
AWMRQwEgYDVQQDEwtSb290IEFnZW5jeQIQtoMOH1HeyJNCKmxxp
3EJRTANBgkqhkiG9w0BAQEFAASBgCi5O+Oe/Wp2Ju/6RkpVRKl
HedkAS7Q0t0j5ht/SEBf5uXkqz2SH23or283msqM07nt52oh
FW/2bU42gpcU8JkU3YenMyC/GCatHdwk5QgsDMZ6jEmcKaQs
RXtux7UVWK6TXbYuDoUyQgH0XafTutWC3HGRw2hz/bva7CkFZZ+
EnMIIDDQYJKoZIhvcNAQcBMBQGCCqGSIb3DQMHBAhBUF7do+aaAI
CCAuiCqzjjI0APbhwStHLw1NXw8sUyNCmPsDhT2KHsXtVNhxXVVhQnA
7A2c6c4H2s6n9X71TGx0UIK2b+Dy6kR4PzzkTROLUWCImp8tt9gh++mz
UUDjicCxUjBUpwUdyPmMw0eD2WV9ZIoJpg47KmoKqdezoj0WUHKzjXp
6n8Tnp6FWvKnP+AgiVPqagagOamPVRJ+Du/x5Kf8PbVTLixIdUOBXVb
G1cd1qROp+o7d9Gfb6G1NDQHLOzG74R0Hbn30ut9NOpXir7QI/ZL4who
2xAm7WAFLJKvS/jvRQCSJo+4iPEdrHCIl+f0Ls93URiZeJKvygleNMEw1
Aze0GAwF5ydHLcohMA2BlcUReCkKi8s7qXM9OMq2mqU8QSnc7c5/keoPiun
DXWj/yBJYWDbw7PXhIuD56Ai8rdDbAjd7EQp1HXVD14X+RLUvKAgLohzm7N2
G1jDXOgkB+IV6d50l+mVMJWHUwUS+g37I3iUfnUWpIzhHmzZK5NOEeFfnEtRo
/did1ufmSMOrblV5WVi18hQ/n5VdmSq4mXYratb4v97BBqmPoSqT45CY8e15FCm
BUF+SJ6I07ZGaHBIk0/Il/DEmezLDUlU7df9vCY/BfpQ27zcVL2twTaLD1Zf7KrB8
J+mBODXiV3x1s06AJ6ZPtWXk9jXWBhWKCcCNMr3S1WBJ4lFjwHvYR8dHCmbKkqmluEwe
2tRHRA8mbTI9G200JAJY/oWqgbpFVr2U1eCU73OQUaXYe4bI10nfByDxiDi4c4O+





I ll keep posting my learnings and implementation of different Scenarios.
Probably next would be Veryfying the Encrypted Message Dycrypting and then
looking at the original message from another application....
Posted on Wednesday, February 28, 2007 6:46 AM | Back to top


Comments on this post: .Net 2.0 Cryptography Implementation - Scenario 1

# re: .Net 2.0 Cryptography Implementation - Scenario 1
Requesting Gravatar...
I have an application that is used to send customer details to particular
office as an attachment to an email message.

What i would like to do is to sign the pdf document using a security
certificate, that way i can protect the details through the internet and
also provide a means for the offices to only see those customers which where
signed with their particular office certificate.

My problem is how to do this in code.

Thanks.

Left by bertone on Apr 11, 2008 4:08 AM

# re: .Net 2.0 Cryptography Implementation - Scenario 1
Requesting Gravatar...
How to decrypted above code
Left by suresh on Nov 05, 2008 3:57 PM

# re: .Net 2.0 Cryptography Implementation - Scenario 1
Requesting Gravatar...
yeah, how to decrypt the above string generated?
Left by rol on Mar 11, 2009 4:21 AM

Your comment:
 (will show your gravatar)


Copyright © Shahed Khan | Powered by: GeeksWithBlogs.net | Join free