Getting X509 Certificates in and out of the
Key Store
1. public static X509Certificate2 GetCert(string thumbprint,
2. StoreName storeName,
3. StoreLocation storeLocation)
4. {
5. // The following code gets the cert from the keystore
6. X509Store store = new X509Store(storeName, storeLocation);
7. [Link]([Link]);
8. X509Certificate2Collection certCollection =
9. [Link]([Link],
10. thumbprint,
11. false);
12. X509Certificate2Enumerator enumerator =
[Link]();
13. X509Certificate2 cert = null;
14. while ([Link]())
15. {
16. cert = [Link];
17. }
18. return cert;
19. }
20. Encrypt and Decrypt a File Using an
X509 Certificate from Your Store
using System;
using [Link];
using [Link].X509Certificates;
using [Link];
using [Link];
// To run this sample use the Certificate Creation Tool ([Link]) to
generate a test X.509 certificate and
// place it in the local user store.
// To generate an exchange key and make the key exportable run the following
command from a Visual Studio command prompt:
//makecert -r -pe -n "CN=CERT_SIGN_TEST_CERT" -b 01/01/2010 -e 01/01/2012 -sky
exchange -ss my
namespace X509CertEncrypt
{
class Program
{
// Path variables for source, encryption, and
// decryption folders. Must end with a backslash.
private static string encrFolder = @"C:\Encrypt\";
private static string decrFolder = @"C:\Decrypt\";
private static string originalFile = "[Link]";
private static string encryptedFile = "[Link]";
static void Main(string[] args)
{
// Create an input file with test data.
StreamWriter sw = [Link](originalFile);
[Link]("Test data to be encrypted");
[Link]();
// Get the certifcate to use to encrypt the key.
X509Certificate2 cert =
GetCertificateFromStore("CN=CERT_SIGN_TEST_CERT");
if (cert == null)
{
[Link]("Certificate 'CN=CERT_SIGN_TEST_CERT' not
found.");
[Link]();
}
// Encrypt the file using the public key from the certificate.
EncryptFile(originalFile,
(RSACryptoServiceProvider)[Link]);
// Decrypt the file using the private key from the certificate.
DecryptFile(encryptedFile,
(RSACryptoServiceProvider)[Link]);
//Display the original data and the decrypted data.
[Link]("Original: {0}",
[Link](originalFile));
[Link]("Round Trip: {0}", [Link](decrFolder +
originalFile));
[Link]("Press the Enter key to exit.");
[Link]();
}
private static X509Certificate2 GetCertificateFromStore(string
certName)
{
// Get the certificate store for the current user.
X509Store store = new X509Store([Link]);
try
{
[Link]([Link]);
// Place all certificates in an X509Certificate2Collection
object.
X509Certificate2Collection certCollection =
[Link];
// If using a certificate with a trusted root you do not
need to FindByTimeValid, instead:
//
[Link]([Link], certName,
true);
X509Certificate2Collection currentCerts =
[Link]([Link], [Link], false);
X509Certificate2Collection signingCert =
[Link]([Link], certName,
false);
if ([Link] == 0)
return null;
// Return the first certificate in the collection, has the
right name and is current.
return signingCert[0];
}
finally
{
[Link]();
}
// Encrypt a file using a public key.
private static void EncryptFile(string inFile,
RSACryptoServiceProvider rsaPublicKey)
{
using (AesManaged aesManaged = new AesManaged())
{
// Create instance of AesManaged for
// symetric encryption of the data.
[Link] = 256;
[Link] = 128;
[Link] = [Link];
using (ICryptoTransform transform =
[Link]())
{
RSAPKCS1KeyExchangeFormatter keyFormatter = new
RSAPKCS1KeyExchangeFormatter(rsaPublicKey);
byte[] keyEncrypted =
[Link]([Link], [Link]());
// Create byte arrays to contain
// the length values of the key and IV.
byte[] LenK = new byte[4];
byte[] LenIV = new byte[4];
int lKey = [Link];
LenK = [Link](lKey);
int lIV = [Link];
LenIV = [Link](lIV);
// Write the following to the FileStream
// for the encrypted file (outFs):
// - length of the key
// - length of the IV
// - ecrypted key
// - the IV
// - the encrypted cipher content
int startFileName = [Link]("\\") + 1;
// Change the file's extension to ".enc"
string outFile = encrFolder +
[Link](startFileName, [Link](".") - startFileName) +
".enc";
[Link](encrFolder);
using (FileStream outFs = new FileStream(outFile,
[Link]))
{
[Link](LenK, 0, 4);
[Link](LenIV, 0, 4);
[Link](keyEncrypted, 0, lKey);
[Link]([Link], 0, lIV);
// Now write the cipher text using
// a CryptoStream for encrypting.
using (CryptoStream outStreamEncrypted = new
CryptoStream(outFs, transform, [Link]))
{
// By encrypting a chunk at
// a time, you can save memory
// and accommodate large files.
int count = 0;
int offset = 0;
// blockSizeBytes can be any arbitrary size.
int blockSizeBytes = [Link] / 8;
byte[] data = new byte[blockSizeBytes];
int bytesRead = 0;
using (FileStream inFs = new FileStream(inFile,
[Link]))
{
do
{
count = [Link](data, 0,
blockSizeBytes);
offset += count;
[Link](data, 0, count);
bytesRead += blockSizeBytes;
}
while (count > 0);
[Link]();
}
[Link]();
[Link]();
}
[Link]();
}
}
}
}
// Decrypt a file using a private key.
private static void DecryptFile(string inFile,
RSACryptoServiceProvider rsaPrivateKey)
{
// Create instance of AesManaged for
// symetric decryption of the data.
using (AesManaged aesManaged = new AesManaged())
{
[Link] = 256;
[Link] = 128;
[Link] = [Link];
// Create byte arrays to get the length of
// the encrypted key and IV.
// These values were stored as 4 bytes each
// at the beginning of the encrypted package.
byte[] LenK = new byte[4];
byte[] LenIV = new byte[4];
// Consruct the file name for the decrypted file.
string outFile = decrFolder + [Link](0,
[Link](".")) + ".txt";
// Use FileStream objects to read the encrypted
// file (inFs) and save the decrypted file (outFs).
using (FileStream inFs = new FileStream(encrFolder + inFile,
[Link]))
{
[Link](0, [Link]);
[Link](0, [Link]);
[Link](LenK, 0, 3);
[Link](4, [Link]);
[Link](LenIV, 0, 3);
// Convert the lengths to integer values.
int lenK = BitConverter.ToInt32(LenK, 0);
int lenIV = BitConverter.ToInt32(LenIV, 0);
// Determine the start postition of
// the ciphter text (startC)
// and its length(lenC).
int startC = lenK + lenIV + 8;
int lenC = (int)[Link] - startC;
// Create the byte arrays for
// the encrypted AesManaged key,
// the IV, and the cipher text.
byte[] KeyEncrypted = new byte[lenK];
byte[] IV = new byte[lenIV];
// Extract the key and IV
// starting from index 8
// after the length values.
[Link](8, [Link]);
[Link](KeyEncrypted, 0, lenK);
[Link](8 + lenK, [Link]);
[Link](IV, 0, lenIV);
[Link](decrFolder);
// Use RSACryptoServiceProvider
// to decrypt the AesManaged key.
byte[] KeyDecrypted = [Link](KeyEncrypted,
false);
// Decrypt the key.
using (ICryptoTransform transform =
[Link](KeyDecrypted, IV))
{
// Decrypt the cipher text from
// from the FileSteam of the encrypted
// file (inFs) into the FileStream
// for the decrypted file (outFs).
using (FileStream outFs = new FileStream(outFile,
[Link]))
{
int count = 0;
int offset = 0;
int blockSizeBytes = [Link] / 8;
byte[] data = new byte[blockSizeBytes];
// By decrypting a chunk a time,
// you can save memory and
// accommodate large files.
// Start at the beginning
// of the cipher text.
[Link](startC, [Link]);
using (CryptoStream outStreamDecrypted = new
CryptoStream(outFs, transform, [Link]))
{
do
{
count = [Link](data, 0,
blockSizeBytes);
offset += count;
[Link](data, 0, count);
}
while (count > 0);
[Link]();
[Link]();
}
[Link]();
}
[Link]();
}
}
}