Click here to Skip to main content
Click here to Skip to main content

Cryptography in .NET

By , 9 Oct 2002
 

Overview

Windows provides a Public Key Infrastructure (PKI) that allows us to store certificates for encryption purposes. To access the this store we had two possibilities in the unmanaged past: The CryptoAPI and the CAPICOM.

The Framework Class Library (= FCL) provies a lot of function for encryption, but the current release doesn't provide any classes for accessing the the certificate store. Fortunately a the Web Services Development Kit (WSDK) Technology Preview adds this functionality; later this will be included in the FCL itself. But in the mean time you have to download the WSDK.

Enumerating The Certificate Store

The article Using WS-Security with the Web Services Development Kit Technology Preview has this nice example:
using Microsoft.WSDK.Security.Cryptography;
using Microsoft.WSDK.Security.Cryptography.X509Certificates;
  ...
private X509CertificateStore store;
  ...
private void Form1_Load( object sender, System.EventArgs e )
{
    store = X509CertificateStore.CurrentUserStore( X509CertificateStore.MyStore );
    store.OpenRead();
    foreach( X509Certificate cert in store.Certificates )
    {
        listBox1.Items.Add( cert.GetName() );
    }
}

Asymmetric Encryption/Signature Example

The following code is the funcionallity of my submitted example. It assumes that you have at least two certificates (with private key!) in your Personal Certificate Store.

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() );
}

Note: The X509Certificate class provides the function ExportParameters and the boolean parameter defines if the private key has to be submitted as well.

A quick note

Favorite person names for encryption examples are Alice, Bob and mean Steve. If you like to see how they are doing in .NET, search your MSDN examples for the excellent example file called PublicKey.cs!

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Manuel Permuy
Web Developer
Switzerland Switzerland
Member
No Biography provided

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
Hint: For improved responsiveness ensure Javascript is enabled and choose 'Normal' from the Layout dropdown and hit 'Update'.
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
Questionwhat is the difference between signing and encryption in rsa?memberMember 151309928 Oct '09 - 2:45 
GeneralIt is giving "Key not valid in use for specified state" Errormemberdhanashekar28 Oct '05 - 1:07 
In the line
rsa.Encrypt( cleartext, false );
 
It is giving error
"Key not valid in use for specified state"
 
What may be reason?
 
Thanks and regards
dhanasekar

Generalusing wse 2.0 or 1.0memberFPARRA812 Sep '05 - 13:17 
GeneralCode cannot work in WSE 2.0memberfrustrated4 Jan '05 - 12:59 
GeneralRe: Code cannot work in WSE 2.0memberdcoolidge2 Aug '05 - 9:37 
QuestionCryptography into Windows Service ?memberPattt9 Dec '04 - 7:40 
AnswerRe: Cryptography into Windows Service ?memberjlandheer18 Jun '05 - 15:28 
AnswerRe: Cryptography into Windows Service ?memberAnouphab8 Dec '06 - 1:49 
Questionhow to remove a private key using CAPICOMmemberchenkaijiang@yahoo.com7 Dec '04 - 2:42 
GeneralUsing more secure hash algorithmmembergceaser14 Oct '04 - 4:16 
GeneralProblem signing a serilized object using CAPICOM.SignedDatamemberEscroto5 Aug '04 - 23:54 
GeneralRe: Problem signing a serilized object using CAPICOM.SignedDatamemberManuel Permuy6 Aug '04 - 13:10 
GeneralRe: Problem signing a serilized object using CAPICOM.SignedDatamemberEscroto6 Aug '04 - 21:28 
GeneralRe: Problem signing a serilized object using CAPICOM.SignedDatamemberManuel Permuy9 Aug '04 - 3:26 
Generalx509certficatestorememberLucia Melotti22 Apr '04 - 2:33 
GeneralCAPICOM+CDOmemberrayback_29 Dec '03 - 7:13 
GeneralRe: CAPICOM+CDOmemberrayback_223 Dec '03 - 23:17 
GeneralRe: CAPICOM+CDOsussgoayeh21 Apr '05 - 16:19 
GeneralRe: CAPCIOM+CDO SendSignedMailmemberrayback_221 Apr '05 - 21:19 
GeneralRe: CAPCIOM+CDO SendSignedMailmemberNoradYeh26 Apr '05 - 22:12 
GeneralRe: CAPCIOM+CDO SendSignedMailmemberrayback_226 Apr '05 - 22:26 
GeneralRe: CAPCIOM+CDO SendSignedMailmemberabygm2 Nov '07 - 2:15 
Generaluse phone numbermembersmail belmokhtar19 Nov '03 - 1:51 
QuestionWhich page is main source?memberStefan Pedersen3 Oct '03 - 11:07 
AnswerRe: Which page is main source?memberManuel Permuy5 Oct '03 - 7:03 
Generalyour URL to WSDK is brokenmembernorm25 Aug '03 - 21:29 
GeneralWSDK becomes WSEsuss.Net wannabe6 Jun '03 - 14:53 
GeneralHelp neededmemberMBuuri22 May '03 - 3:07 
GeneralRe: Help neededmemberMarcello Drewanz18 Jun '03 - 7:25 
GeneralYou get a 5...adminChris Maunder25 Feb '03 - 9:00 
General"I am Emmet Smith!"memberrflagg24 Feb '03 - 17:35 
GeneralRe: "I am Emmet Smith!"memberManuel Permuy4 Feb '04 - 13:48 
GeneralCertificate issuer chain...memberFred James11 Feb '03 - 2:13 
GeneralVerify the CertificatememberFred James11 Feb '03 - 2:12 
GeneralRe: Verify the CertificatememberWhyIamhere30 Apr '04 - 9:12 
GeneralCAPICOMmemberpoojavedi29 Jan '03 - 0:00 
QuestionCAPICOM Necessary?memberSteveC881 Oct '02 - 8:45 
AnswerRe: CAPICOM Necessary?memberManuel Permuy4 Oct '02 - 13:01 
GeneralThe X509Certificate class provides the function ExportParameterssussAnonymous28 Sep '02 - 7:20 
GeneralRe: The X509Certificate class provides the function ExportParametersmemberManuel Permuy30 Sep '02 - 11:16 
GeneralRe: The X509Certificate class provides the function ExportParameterssussAnonymous6 Oct '02 - 3:56 
GeneralRe: The X509Certificate class provides the function ExportParametersmemberManuel Permuy6 Oct '02 - 13:38 
GeneralRe: The X509Certificate class provides the function ExportParameterssussAlex Butcher22 Dec '02 - 22:28 
GeneralRe: The X509Certificate class provides the function ExportParametersmemberSteveC-A929 Jan '04 - 9:03 
Question"FCL"?sitebuilderUwe Keim25 Sep '02 - 20:59 
AnswerRe: "FCL"?sussAnonymous25 Sep '02 - 21:26 
AnswerRe: "FCL"?memberManuel Permuy27 Sep '02 - 5:52 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web02 | 2.6.130516.1 | Last Updated 10 Oct 2002
Article Copyright 2002 by Manuel Permuy
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid