|
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.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.