CryptoSys Home > PKI > CryptoSys PKI C# Interface

CryptoSys PKI C# Interface


The .NET Class Library for the CryptoSys PKI provides a safe, clean interface to .NET methods. These can be used in an almost identical manner in both C# and VB.NET projects. For more details see .NET Class Library Interface.

Doing RSA Encryption and Signing with C#

Here is a possible method to encrypt some data given the recipient's X.509 certificate.

WARNING: Note that this is just an example that only works for very short messages (shorter than the key length in bytes). The usual method with RSA encryption is to use it to encrypt and transport a randomly-generated session key (content-encryption key, CEK) and then use that key with faster, conventional symmetric encryption like AES-128 or Triple DES to encrypt the main body of the message.
public static byte[] RsaEncryptBytes(byte[] inputData, string certFile)
{
	StringBuilder sbPublicKey;
	byte[] block;
	byte[] outputData;
	int klen;
	// 1. Read the public key from the recipient's X.509 certificate
	sbPublicKey = Rsa.GetPublicKeyFromCert(certFile);
	if (sbPublicKey.Length == 0)
	{
		Console.WriteLine("ERROR reading certificate");
		return new byte[0];
	}
	// 2. Make an RSA data block of same length in bytes as key

	// using EME-PKCS1-v1_5 encoding
	klen = Rsa.KeyBytes(sbPublicKey.ToString());
	if (klen <= 0)
	{
		Console.WriteLine("ERROR: invalid public key");
		return new byte[0];
	}
	block = Rsa.EncodeMsg(klen, inputData, Rsa.EncodeFor.Encryption);
	// 3. Encrypt with RSA public key
	outputData = Rsa.RawPublic(block, sbPublicKey.ToString());
	if (outputData.Length == 0)
	{
		Console.WriteLine("ERROR: failed to encrypt");
		return new byte[0];
	}
	// 4. Clean up
	Wipe.Data(block);
	Wipe.String(sbPublicKey);

	// 5. Output "ciphertext"
	return outputData;
}

This could be called like this

byte[] inputData = System.Text.Encoding.Default.GetBytes("Hello world!");
string certFile = "BobRSASignByCarl.cer";
// Output: byte array of "ciphertext"
byte[] outputData = RsaEncryptBytes(inputData, certFile);
// Display output in hex format
Console.WriteLine("ENC={0}", Cnv.ToHex(outputData));

To decrypt, we could do this:


public static byte[] RsaDecryptBytes(byte[] inputData, string priKeyFile, string password)
{
	StringBuilder sbPrivateKey;
	byte[] block;
	byte[] outputData;

	// 1. Read in the private key from the encrypted key file
	sbPrivateKey = Rsa.ReadEncPrivateKey(priKeyFile, password);
	if (sbPrivateKey.ToString().Length == 0)
	{
		Console.WriteLine("ERROR reading private key file");
		return new byte[0];
	}
	// 2. Decrypt with private key
	block = Rsa.RawPrivate(inputData, sbPrivateKey.ToString());
	if (block.Length == 0)
	{
		Console.WriteLine("Decryption error");
		return new byte[0];
	}
	// 3. Extract the message from the encryption block
	outputData = Rsa.DecodeMsg(block, Rsa.EncodeFor.Encryption);
	if (outputData.Length == 0)
	{
		Console.WriteLine("Decryption error");
		return new byte[0];
	}
	// 4. Clean up - NB should do this on error, too.
	Wipe.Data(block);
	Wipe.String(sbPrivateKey);

	// 5. Output "plaintext"

	return outputData;
}

Download the full source code that demonstrates this encryption and decryption, as well as methods to carry out signing and verification in RsaExample.cs (zipped version, 3 kB). To compile, add this item to a new C# Console Application project and create a reference to diCrSysPKINet.dll. The test certficates and private key files used in the example are in pkiCsharpTestFiles.zip.

References

Contact us

To contact us or comment on this page, please send us a message.

[Go to top]

This page last updated 27 October 2011. Reformatted for HTML5 on 12 June 2020.