Click here to Skip to main content
15,894,646 members
Articles / Programming Languages / C#

Encrypt and Decrypt Data with C#

Rate me:
Please Sign up or sign in to vote.
4.78/5 (114 votes)
18 May 2006CPOL3 min read 756.5K   70K   159  
Encrypt and decrypt important data with C# and play
using System;
using System.Text;
using System.Diagnostics;
using System.Security.Cryptography;
using Microsoft.WSDK.Security.Cryptography.X509Certificates;

namespace Codeproject.Cryptography
{
	class CryptographyApp
	{
		[STAThread]
		static void Main(string[] args)
		{
			try
			{
				//
				// GENERAL CODE TO READ THE CERTIFICATES FROM THE WINDOWS PKI INFRASTRUCTURE
				//
				// BEGINNER-TIP: Start MMC (=Microsoft Management Console) and select "Add-in/remove Snapin"
				// from the "Console" menu. Now press "Add.." button. Select "Certificates" in the list and
				// press "Add" button. You have the choise to select "My user account" or "Computer account".
				// Then press "Finish" and "Close" and start exploring the installed certificates... 
				// Each store has a "Personal" section with is BTW represented by the letters "MY".
				// Also interessting is the "Trusted root" certificates, there you see all the Certificate
				// Issuer that you trust, there is quite a lot and sometimes it's a good idea to delete
				// all of them and only add the one you need or really trust, for security resasons.
				//

				// Open private certificate store of current user
				X509CertificateStore store = X509CertificateStore.CurrentUserStore( X509CertificateStore.MyStore );
				store.OpenRead();

				// Read e.g. the first two certificate
				X509Certificate sender = (X509Certificate)store.Certificates[0];
				X509Certificate receiver = (X509Certificate)store.Certificates[1];

				// Let's see who we are dealing with... - ps: not nessesary for the following code
				string sender_serial = sender.GetName();
				string receiver_serial = receiver.GetName();

				//
				// SENDER-SIDE CODE
				//

				// SENDER-SIDE: Extract own private keys and receiver's public key
				RSAParameters sender_private = sender.Key.ExportParameters( true );
				RSAParameters receiver_public = receiver.Key.ExportParameters( false );

				// SENDER-SIDE: Asymmetric encryption with receivers's public key
				RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
				rsa.ImportParameters( receiver_public ); 
				byte[] cleartext = ASCIIEncoding.ASCII.GetBytes("test");
				byte[] cipher = rsa.Encrypt( cleartext, false );
				
				// SENDER-SIDE: Sign the cipher with own private key
				rsa = new RSACryptoServiceProvider();
				rsa.ImportParameters( sender_private );
				byte[] signature = rsa.SignData( cipher, new SHA1CryptoServiceProvider() );

				//
				// TODO: TRANSFER DATA OVER UNSECURE CHANNEL...
				//

				// RECEIVER-SIDE: Get own private key and sender's public key
				RSAParameters receiver_private = receiver.Key.ExportParameters( true );
				RSAParameters sender_public = sender.Key.ExportParameters( false );

				// RECEIVER-SIDE: Verify signature with sender's public key
				//
				// Note: You are ONLY verifying the signature and NOT verifying the Certificate!
				// It's corresponding to the CAPICOM call SignedData.Verify( CAPICOM_VERIFY_SIGNATURE_ONLY )
				// I did not yet find out how we can use the .NET library to verify the Certificate
				// against the issuer-chain. If someone knows how to do this, and not using interop
				// and the SignedData.Verify( CAPICOM_VERIFY_SIGNATURE_AND_CERTIFICATE ), I would be
				// very, very, very happy - because this is a requirement in the software I'm developing
				// currently and if we can't do that I have to do CAPI-interop :-(
				// At the moment I think that there is no simple function call for this and this s***s.
				// Maybe it's possible to walk throw the chain-of-issuers and validate the fingerprint
				// this the public key of the issuer. But I don't know enough about that....
				// ANY HELP TO THIS POINT IS MORE THAN WELCOME
				//
				rsa = new RSACryptoServiceProvider();
				rsa.ImportParameters( sender_public );
				if( rsa.VerifyData( cipher, new SHA1CryptoServiceProvider(), signature ) )
				{
					// RECEIVER-SIDE: Asmymetirc decryption with own private key
					rsa.ImportParameters( receiver_private );
					byte[] cleartext_after_decription = rsa.Decrypt( cipher, false );

					// Check result
					Debug.Assert( ASCIIEncoding.ASCII.GetString( cleartext ) ==
						ASCIIEncoding.ASCII.GetString( cleartext_after_decription ),
						"Ups, the cleartext input is not equal the cleartext output..." );
				}
				else
					Debug.Assert( false, "Ups, check signature failed!" );
			}
			catch( Exception e )
			{
				// NOTE: the following exception, that may occure during 'ExportParameters( true )'
				//
				//   System.Security.Cryptography.CryptographicException
				//   "Key information could not be exported from the cryptographic service 
				//    provider (CSP) for this implementation." }"
				// 
				// Can have one of the following reasons:
				// + The certificate was NOT imported with the flag "Mark the private key as exportable"
				// + The type "SSL Server Authentication(40)" and is in a CurrentUser store and not in
				//   the LocalComputer store. See certificate details in the MMC under "NetscapeCertType".
				//   IMHO: This reason is very wicked and I don't understand it!!


				Debug.Assert( false, e.ToString() );
			}
		}
	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer Pöyry Infra GmbH
Austria Austria
I am Syed Moshiur Murshed from Bangladesh. I studied BSC in Computer Science at American International University Bangladesh(www.aiub.edu). And then MSC in Software Technology at Stuttgart University of Applied Science, Germany(www.hft-stuttgart.de). Currently I am employed as a Software Engineer at Pöyry Infra GmbH in Salzburg, Austria since 04-2011.
I have been learning C# for quite some time and Enjoying it.

Comments and Discussions