Return to HomePage




Retrieve an RSA Key Pair from the Registry and Decrypt a Message (VB.NET)



Applies to

* .NET Framework 2.0
* VB.NET


Summary

The purpose of this code snippet is to illustrate how to retrieve a public keypair stored in the registry using the Data Protection API (DPAPI) and decrypt a message using that key pair.

Objectives

* Make use of a securely stored RSA keypair for to decrypt an encrypted message
* Illustrate how securely stored keys in the registry and using the DPAPI can be easy to implement


Scenarios

* Distributed client-server architecture where clients need to send confidential encrypted messages to the server but don't need to ever read those messages
* Application does not want to maintain a dedicated key store for encryption purposes

Solution Example

Public Shared Function RetrieveRSAKeyPairAndDecryptMessage(encrypted() As Byte) As Byte()
		   		' Retrieve the keypair from the registry, decrypt using the DPAPI
		   		' and store the serialized key data as an XML string 
		   		Dim [encryptedKeyPair] As Byte() = Registry.GetValue("HKEY_CURRENT_USER\RSAKeyPair", "KeyData", Nothing)
		   		Dim [keyPairBytes] As Byte() = [ProtectedData.Unprotect(encryptedKeyPair,] Nothing, 		[DataProtectionScope.CurrentUser)]
		   		Dim [keyPairXml] As String = [UnicodeEncoding.ASCII.GetString(keyPairBytes)]
	

		   		' Create a new RSA CSP in which to load the public/private key 
		   		' data retrieved from the registry
		   		Dim retrievedRSA As New [RSACryptoServiceProvider()]
		   		[retrievedRSA.FromXmlString(keyPairXml)]
	

		   		' Decrypt message and return
		   		Return retrievedRSA.Decrypt(encrypted, False)
	
End Function


Problem Example

The following example demonstrates the retrieval of an RSA key pair containing private key material from the file system.

' fileName is a string containing a path location with a serialized RSA key pair
' encrypted is a byte array containing an encrypted message for decryption
' Open up the public key file and read into a string
Dim keyReader As New StreamReader(fileName)
Dim keyPairXml As String = keyReader.ReadToEnd()
keyReader.Close()

' Create a new RSA CSP in which to load the public/private key
' data retrieved from the registry
Dim retrievedRSA As New RSACryptoServiceProvider()
retrievedRSA.FromXmlString(keyPairXml)

' Decrypt message
retrievedRSA.Decrypt(encrypted, False)

* If the filesystem is compromised, the private key material may be exposed
* Extra management required to ensure that ACL's are securely set for files that contain key data
* In alternate settings, lack of encryption when sending message exposes sensitive data to eavesdropping while in transit


Test Case

The following classes must be included in any project making use of the sample code provided above:

Imports System.IO
Imports System.Security
Imports System.Security.AccessControl
Imports System.Security.Cryptography
Imports Microsoft.Win32

Use the solution example above and the following code to encrypt an example using the registry-stored public key and then decrypt using the solution example:

Sub Main(args() As String)
		   		' Read public key into a string
		   		Dim [publicKeyXml] As String = "<RSAKeyValue>" 	+ "<Modulus>tnLAgAJwXXxYj+2QPX6q/mHZZf23xSvvovoBlZ1Y7RbTlkY4N2nlcGxfR6mQcTTWKfWShQ7yEaX6rVfhhRhd	aHLCsg7g3AmW2BsoBxWUijD81ZeNKyWrw8t0gjnigNR46+PqO1Xi7R9aA+PgaluhuZBBgJK2wIAlRJSPlTr5OjDr4vJlZiAG	/VqmJVXioPfv1QI2hfLM86JgIcrD47L0K44tKwyhAj4PN1nsomjPeb0P9m9t3od/c+yZGKk+iJ1nwQwG02H/EXROaO6YFKb3	xijNv69gv+ZLGc+qssXs7Bs7CdzqmQvSylxuXkYz5bQG++raYWm4l056WhtIRG8mqQ==</Modulus>" 	+ "<Exponent>AQAB</Exponent>" + "</RSAKeyValue>"
	

		   		' Encrypt a message using our key and write out the results
		   		Dim msg As String = "The quick brown fox jumped over the lazy dog"
		   		Dim encrypted As Byte() = [ReadRSAPublicKeyAndEncryptMessage(publicKeyXml,] msg)
		   		Console.WriteLine("Encrypted data:")
		   		[Console.WriteLine(Convert.ToBase64String(encrypted))]
	

		   		' Retrieve RSA [KeyPair] from registry and decrypt a message
		   		Dim decrypted As Byte() = [RetrieveRSAKeyPairAndDecryptMessage(encrypted)]
		   		[Console.WriteLine(ControlChars.Lf] + "Decrypted data:")
		   		[Console.WriteLine(Encoding.ASCII.GetString(decrypted))]
	
End Sub


Shared Function ReadRSAPublicKeyAndEncryptMessage(xmlKeyData As String, fileName As String) As Byte()
		   		' Create a new RSA CSP in which to load the public key data from file
		   		Dim yourRSA As New [RSACryptoServiceProvider()]
		   		[yourRSA.FromXmlString(xmlKeyData)]
	

		   		' Encrypt a message and return
		   		Dim original As Byte() = Encoding.ASCII.GetBytes("The quick brown fox jumped over the lazy dog")
		   		Return yourRSA.Encrypt(original, False)
	
End Function


Expected Result

Encrypted data:
YQdGxH+fyXEVjaoToOT4kVR00nmNv4xBWLRP5hyk7qz2zS9a64I0Ug9S99shDWvmbIT/nsKTkmPu8gZG
Xx3R7zNXn44KKKIlXKcIxvfXHHnkuMuX3tXdpLZKPhPKcG09nFVtxdKehOnvVQEr5Wyp54XnkqU3B6Vp
Bui6wabN/dqrhE0ziqpAkM2NbhU5h38mfo6brq0Ug9Tns9xj4mAD5AwDvqKlkumr9qS94czPzt5ECFv8
rX4/HBvl/PhQZzsYt3xHwkQRDtTA5zf1G5ey9pOAKpzPtLI/2LShaJVujo/fQifoLU1vCa1BoMON
Cpk0A1B4zIm5aTpYzp6w==

Decrypted data:
The quick brown fox jumped over the lazy dog


More Information

RSA is an algorithm for public key (also knows as asymmetric) cryptography in which distinct public and private keys are created. Encryption operations makes use of the public key while decryption requires the private key. This offers an advantage over symmetric cryptography because the secret key used to decrypt a message does not need to be shared in order to support encryption of messages to a recipient.

The RSA private key must be securely stored in order to maintain the confidentiality of data encrypted using an individual's public RSA key. However, the public key can be freely distributed by the owner of the key pair to anyone who wishes to send an encrypted message to that owner.


Additional Resources

* RSACryptoServiceProvider (.NET): http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemsecuritycryptographyrsacryptoserviceproviderclassctortopic.asp
* Cryptography (.NET): http://msdn.microsoft.com/library/en-us/dnpag2/html/PAGGuidelines0003.asp?frame=true#pagguidelines0003_cryptography


Attributes

* Applies To: .NET Framework 2.0, VB
* Category: Cryptography
* Author: Jonathan Bailey




Return to HomePage
Microsoft Communities