Cryptography and .NET Framework - Part 3 (Public Key Encryption)
Introduction
In the
Part 2 of this series we learnt to use Secret Key Encryption techniques
using Triple-DES algorithm. More often to transfer data encrypted via secret key
encryption public key encryption is used. This puts one extra layer of security
over the data being transferred. From
Part 1 we know that public key encryption consists of two keys - public key
and private key. Data encrypted by public key can be decrypted only by the
corresponding private key and vice a versa. One of the most popular algorithm
for encrypting and decrypting data using this technique is RSA. The acronym RSA
stands for Rivest, Shamir, and Adelman who are the inventors of the technique.
The .NET framework provides a class called RSACryptoServiceProvider that
encapsulates this algorithm. In this article we are going to learn how to use
this class to secure your data.
Developing a class for encryption and decryption
Many developers don't want to go into the internals of Cryptography. They
simply need a quick and easy way to secure their data. So we are going to
develop such reusable class that will do the job of encrypting and decrypting
for us.
We will create a class called PublicKeySecurityHelper which will have two
methods - Encrypt and Decrypt. In addition we will also create a helper class
called MyRSAInfo. This class will simply store certain pieces of data (such as
public key and private key).
Here, is the complete code of the class.
Imports System.Security.Cryptography
Imports System.IO
Imports System.Text
Public Class PublicKeySecurityHelper
Public Function Encrypt(ByVal strData As String) As MyRSAInfo
Dim myrsa As New MyRSAInfo
Dim p As CspParameters = New CspParameters
p.Flags = CspProviderFlags.UseMachineKeyStore
myrsa.Parameters = p
Dim rsa As RSACryptoServiceProvider =
New RSACryptoServiceProvider(p)
Dim data() As Byte =
rsa.Encrypt(Encoding.Unicode.GetBytes(strData), False)
myrsa.PublicKey = rsa.ToXmlString(False)
myrsa.PrivateKey = rsa.ToXmlString(True)
myrsa.Data = data
Return myrsa
End Function
Public Function Decrypt(ByVal myrsa As MyRSAInfo) As Byte()
Dim rsa As RSACryptoServiceProvider =
New RSACryptoServiceProvider(myrsa.Parameters)
rsa.FromXmlString(myrsa.PublicKey)
Dim data() As Byte = rsa.Decrypt(myrsa.Data, False)
Return data
End Function
End Class
Public Class MyRSAInfo
Public PublicKey As String
Public PrivateKey As String
Public Parameters As CspParameters
Public Data() As Byte
End Class
Let's dissect the code step by step:
Encrypting data
- First we import the required namespaces. Especially
System.Security.Cryptography is important one because it contains our core
class RSACryptoServiceProvider
- We create a method called Encrypt() that accepts the string to be
encrypted and returns an instance of a class called MyRSAInfo
- MyRSAInfo is our custom class defined at the bottom of the code. It
consists of four public members - PublicKey, PrivateKey, Parameters and Data
- The PublicKey and PrivateKey members store the generated public key and
private key respectively.
- The Parameters variable is of type CspParameters. This is used to
automatically generate public and private keys and reuse them later on.
- The Data is an array of bytes and stores the encrypted version of the
data
- Inside the Encrypt() method we create an instance of CspParameters class
and set its Flag property to CspProviderFlags.UseMachineKeyStore. This
enumerated value specifies from where the key information should be picked
up i.e. from default key container or from machine level key store.
- Then we create new instance of RSACryptoServiceProvider class passing
the CspParameters instance.
- We then call Encrypt() method of RSACryptoServiceProvider class and pass
data to be encrypted. Since this parameter is byte array we convert our
string into byte array using GetBytes() method. The second parameter of the
method indicates whether to use OAEP padding (true) or PKCS#1 v1.5 padding
(false). The former can be used only on Windows XP machines and hence we
pass False. The Encrypt() method of RSACryptoServiceProvider class returns a
byte array that contains encrypted version of the data.
- Finally, we fill all the members of MyRSAInfo class and return to the
caller. Note how we call ToXmlString() method first passing False and then
passing True to get public and private keys respectively.
Decrypting data
- In order to decrypt the data we create a method called Decrypt() that
accepts an instance of MyRSAInfo class. This instance must be the one
returned by the Encrypt() method explained earlier.
- Inside Decrypt() method we create an instance of
RSACryptoServiceProvider class again passing the same CspParameters.
- We then call FromXmlString() method of the RSACryptoServiceProvider
class and pass the public key generated before.
- Finally, we call Decrypt() method of RSACryptoServiceProvider class and
pass the encrypted data. The second parameter of Decrypt method has the same
significance as that of the corresponding parameter of Encrypt() method
Download
Complete source code along with a sample usage is available for download with
this article (see top).
Summary
Public key encryption is a secure way to transfer data over networks. The
fact that the private key is not sent in unsafe manner makes it more secure and
robust. This technique is used in Secure Socket Layer (SSL) or HTTPS based web
sites. The .NET framework class RSACryptoServiceProvider allows you to generate
public and private keys, encrypt and decrypt data. In the next article we will
learn about digital signatures. Stay tuned!