Home > Articles > Security > Network Security

This chapter is from the book

This chapter is from the book

Programming with .NET Asymmetric Cryptography

In this section, we look at the RSAAlgorithm and SavingKeysAsXml example programs provided for this chapter. These two code examples show how to encrypt and decrypt using the RSA algorithm as well as how to store and retrieve key information using an XML format. The RSA code example uses the concrete RSACryptoServiceProvider class. Figure 4-2 shows where this class resides in the class hierarchy, under the abstract AsymmetricAlgorithm class. The other concrete class, DSACryptoServiceProvider, is discussed in Chapters 5, where we look at digital signatures.

04fig02.gifFigure 4-2. The asymmetric algorithm class hierarchy.

An RSA Algorithm Example

The RSAAlgorithm example uses the Encrypt method of the RSACryptoServiceProvider class. This method takes two parameters, the first of which is a byte array containing the data to be encrypted. The second parameter is a boolean that indicates the padding mode to be used. Padding is required, since the data to be encrypted is usually not the exact number of required bits in length. Since the algorithm requires specific bit-sized blocks to process properly, padding is used to fill the input data to the desired length. If this second parameter is true, then the improved OAEP16 padding is used. Otherwise, the traditional PKCS#1 v1.5 padding is used. PKCS#1 v1.5 has been traditionally the most commonly used padding scheme for RSA usage. However, it is recommended that all new RSA applications that will be deployed on platforms that support OAEP should use OAEP. Note that OAEP padding is available on Microsoft Windows XP and Windows 2000 with the high-encryption pack installed. Unfortunately, previous versions of Windows do not support OAEP, which will cause the Encrypt method, with the second parameter set to true, to throw a CryptographicException. The Encrypt method returns the resulting encrypted data as a byte array. Here is the syntax for the Encrypt method.

public byte[] Encrypt(
   byte[] rgb,
   bool fOAEP
);

The complementary method to Encrypt is of course Decrypt. You can probably guess how it works. The second parameter is a byte array containing the ciphertext to be decrypted. The second parameter is the same as that in the Encrypt method, indicating the padding mode, as described previously. The return value is a byte array that will contain the resulting recovered plaintext. Here is the syntax for the Decrypt method.

public byte[] Decrypt(
   byte[] rgb,
   bool fOAEP
)

Figure 4-3 shows the RSAAlgorithm example being used to encrypt and decrypt a plaintext message. You enter the plaintext in the TextBox at the top of the form. You then click on the Encrypt button, which fills in all but the last form field, including the resulting ciphertext and RSA parameters that were used. You then click on the Decrypt button, which displays the recovered plaintext in the field at the bottom of the form. Of course, the recovered plaintext should be identical to the original plaintext.

04fig03.jpgFigure 4-3. The RSAAlgorithm example program.

Now let's look at the code in the RSAAlgorithm example code. The buttonEncrypt_Click method is called when the user clicks on the Encrypt button. This encrypts the contents of the plaintext textbox using the established public RSA key. The public/private RSA key pair is provided by the program automatically when it starts, but it may subsequently be changed using the New RSA Parameters button. There are a few places in the code where user interface elements are being enabled and disabled, which are not germane to our focus on RSA functionality. Therefore, these user interface code sections are ignored here. If you are curious about how these user interface details work, please study the simple code sections following each of the //do UI stuff comments.

We first generate the initial RSA parameters by calling the GenerateNewRSAParams method in the RSAAlgorithm_Load method. The GenerateNewRSAParams method is also called each time the user clicks on the New RSA Parameters button, which is handled by the buttonNewRSAParams_Click method. The GenerateNewRSAParams method is very simple. It just creates an RSACryptoServiceProvider class object, stores its public and private RSA parameters by calling the RSA class's ExportParameters method, and displays a few of the more important of these parameters in the user interface. These RSA parameters are actually stored in two fields of type RSAParameters. The RSAParameters field named rsaParamsExcludePrivate gets a copy of the public-only RSA parameters (i.e., the modulus and exponent values only), which is required for encryption purposes in the buttonEncrypt_Click method. The other RSAParameters field, named rsaParamsIncludePrivate gets a copy of the combined public and private RSA parameters, which is required in the buttonDecrypt_Click method.

Here is the GenerateNewRSAParams method. Note that the ExportParameters method is called twice. The first time, the parameter passed into this method is true, and the second time, it is false. Passing true indicates that you want to include all key parameter information, including the private key information. False indicates that only the public key information is to be stored. We separate these cases into two distinct fields to demonstrate how the encryption will use only the public information, but the decryption will use both the public and private key information. This is a crucial point in understanding asymmetric cryptography. This would perhaps be even clearer if we broke the encryption and decryption portions of this example into two separate applications, but this example is provided as a simple monolithic program purely for easy study. You should at some point take a moment to verify that the encryption and decryption functions in this program do indeed use only their own appropriate version of this RSA parameter information, using the corresponding ImportParameters method.

private void GenerateNewRSAParams()
   {
   //establish RSA asymmetric algorithm
   RSACryptoServiceProvider rsa =
   new RSACryptoServiceProvider();
   
   //provide public and private RSA params
   rsaParamsIncludePrivate =
   rsa.ExportParameters(true);
   
   //provide public only RSA params
   rsaParamsExcludePrivate =
   rsa.ExportParameters(false);
   

When we create an instance of the RSACryptoServiceProvider class, we actually get the RSA implementation provided by the underlying cryptographic service provider (CSP). This class is directly derived from the RSA class. The RSA class allows other RSA implementations to be implemented as other derived classes; however, the CSP implementation is currently the only one available.

The two fields that store the RSA parameter information when ExportParameters is called are declared as RSAParameters type fields, as shown in the following code snippet. The rsaParamsExcludePrivate filed will be used for encryption, and the rsaParamsIncludePrivate field will be used in decryption in this example.

//public modulus and exponent used in encryption
RSAParameters rsaParamsExcludePrivate;
   
   //public and private RSA params use in decryption
   RSAParameters rsaParamsIncludePrivate;
   

In the buttonEncrypt_Click method we then create a new instance of RSACryptoServiceProvider class, and we initialize it with the stored public key information by calling the RSA object's ImportParameters method, specifying rsaParamsExcludePrivate as the parameter. Next, we obtain the plaintext in the form of a byte array named plainbytes. Finally, we perform the main function of this method by calling on the Encrypt method of the RSA object. This returns another byte array, which is an instance field named cipherbytes. This is an instance field rather than a local variable, because we need to communicate this byte array to the decryption method, and local variables are not maintained across method calls.

private void buttonEncrypt_Click(
   object sender, System.EventArgs e)
   {
   //do UI stuff
   ...
   
   //establish RSA using parameters from encrypt
   RSACryptoServiceProvider rsa =
   new RSACryptoServiceProvider();
   
   //import public only RSA parameters for encrypt
   rsa.ImportParameters(rsaParamsExcludePrivate);
   
   //read plaintext, encrypt it to ciphertext
   byte[] plainbytes =
   Encoding.UTF8.GetBytes(textPlaintext.Text);
   cipherbytes =
   rsa.Encrypt(
   plainbytes,
   false); //fOAEP needs high encryption pack
   
   //display ciphertext as text string
   ...
   
   //display ciphertext byte array in hex format
   ...
   
   //do UI stuff
   ...
   }
   ...
   //variable communicated from encrypt to decrypt
   byte[] cipherbytes;
   

The buttonDecrypt_Click method is called when the user clicks on the Decrypt button. Again, an RSA object is created. The RSA object is repopulated with the information provided by calling the RSA object's ImportParameters method, but this time, the parameter to this method is the rsaParamsIncludePrivate, which includes both public and private RSA key information. The plaintext is then obtained by calling the Decrypt method of the RSA object. Since a matching set of RSA algorithm parameters were used for both encryption and decryption, the resulting plaintext matches perfectly with the original plaintext.

private void buttonDecrypt_Click(
   object sender, System.EventArgs e)
   {
   //establish RSA using parameters from encrypt
   RSACryptoServiceProvider rsa =
   new RSACryptoServiceProvider();
   
   //import public and private RSA parameters
   rsa.ImportParameters(rsaParamsIncludePrivate);
   
   //read ciphertext, decrypt it to plaintext
   byte[] plainbytes =
   rsa.Decrypt(
   cipherbytes,
   false); //fOAEP needs high encryption pack
   
   //display recovered plaintext
   ...
   
   //do UI stuff
   ...
   }
   
   ...
   //variable communicated from encrypt to decrypt
   byte[] cipherbytes;
   

Saving Keys as XML

You might not always want to transmit the contents of the ExportParameters object directly between arbitrary applications, especially between different platforms and cryptographic libraries. After all, the ExportParameters class is very Microsoft- and .NET-specific. A much more convenient and generalized format for transmitting a public key is via an XML stream.17 The SavingKeysAsXml example program shows how to read and write keys in XML format. This example is almost identical to the RSAAlgorithm example we just looked at. The significant difference is that we use XML for storing and transmitting the public key information from the encryption method to the decryption method rather than use an ExportParameters object. Another slight difference is that the RSA parameter information is not displayed; the contents of the key XML stream is displayed instead, but that is of course only a user interface detail.

For simplicity and ease of demonstration, this example is again implemented as a single monolithic application. This is purely for ease of demonstration, and it would be straightforward to take this example and break it up into two separate encrypting and decrypting programs. Our purpose here is to show both the sending (encrypting) and receiving (decrypting) code and how the XML data is used to store key information between the two. To make this example somewhat more realistic, the XML data is written to a file rather than stored in a shared field, as was done in the previous example. This simulates the case in a real-world scenario in which you would need to read and write this information to some type of external storage or perhaps via a socket stream. From the programmer's perspective, the most significant change from the previous example is that the calls to the ExportParameters and ImportParameters methods of the RSACryptoServiceProvide class have been replaced with calls to the ToXmlString and FromXmlString methods of the same class. Once again, a boolean parameter is used to indicate whether private information is included or excluded in the stored key information.

Here is the GenerateNewRSAParams method, which serves the same basic purpose as described in the previous program example. The difference is that we are storing the key information in XML format, in two files named PublicPrivateKey.xml and PublicOnlyKey.xml, by calling the ToXmlString method with a boolean parameter. These two files will be used later in the encryption and decryption functions.

private void GenerateNewRSAParams()
   {
   //establish RSA asymmetric algorithm
   RSACryptoServiceProvider rsa =
   new RSACryptoServiceProvider();
   
   //provide public and private RSA params
   StreamWriter writer =
   new StreamWriter("PublicPrivateKey.xml");
   string publicPrivateKeyXML =
   rsa.ToXmlString(true);
   writer.Write(publicPrivateKeyXML);
   writer.Close();
   //provide public only RSA params
   writer =
   new StreamWriter("PublicOnlyKey.xml");
   string publicOnlyKeyXML =
   rsa.ToXmlString(false);
   writer.Write(publicOnlyKeyXML);
   writer.Close();
   
   //display public and private RSA key
   textBoxPublicKeyXML.Text = publicPrivateKeyXML;
   
   //do UI stuff
   ...
   }
   

Next, let's look at the buttonEncrypt_Click method. We create a new RSACryptoServiceProvider object and initialize it by calling the FromXmlString method with the public key information stored in the PublicOnlyKey.xml file. Then we call the RSA object's Encrypt method to perform the cryptographic transformation on the plaintext.

private void buttonEncrypt_Click(
   object sender, System.EventArgs e)
   {
   //do UI stuff
   ...
   
   //establish RSA asymmetric algorithm
   RSACryptoServiceProvider rsa =
   new RSACryptoServiceProvider();
   
   //public only RSA parameters for encrypt
   StreamReader reader =
   new StreamReader("PublicOnlyKey.xml");
   string publicOnlyKeyXML = reader.ReadToEnd();
   rsa.FromXmlString(publicOnlyKeyXML);
   reader.Close();
   
   //read plaintext, encrypt it to ciphertext
   byte[] plainbytes =
   Encoding.UTF8.GetBytes(textPlaintext.Text);
   cipherbytes =
   rsa.Encrypt(
   plainbytes,
   false); //fOAEP needs high encryption pack
   
   //display ciphertext as text string
   ...
   //display ciphertext byte array in hex format
   ...
   
   //do UI stuff
   ...
   }
   

Finally, the buttonDecrypt_Click method creates its own new RSACryptoServiceProvider object, but it initializes it by calling FromXmlString using the PublicPrivateKey.XML file, which contains both public and private key information—a requirement of RSA decryption.

private void buttonDecrypt_Click(
   object sender, System.EventArgs e)
   {
   //establish RSA using key XML from encrypt
   RSACryptoServiceProvider rsa =
   new RSACryptoServiceProvider();
   
   //public and private RSA parameters for encrypt
   StreamReader reader =
   new StreamReader("PublicPrivateKey.xml");
   string publicPrivateKeyXML = reader.ReadToEnd();
   rsa.FromXmlString(publicPrivateKeyXML);
   reader.Close();
   
   //read ciphertext, decrypt it to plaintext
   byte[] plainbytes =
   rsa.Decrypt(
   cipherbytes,
   false); //fOAEP needs high encryption pack
   
   //display recovered plaintext
   ...
   
   //do UI stuff
   ...
   }
   

Figure 4-4 shows the SavingKeysAsXml example being used to encrypt and decrypt a plaintext message. Notice the XML display shows contents of the PublicPrivateKey.xml file that is being used by the decryption method. It is a bit difficult to read with all the XML elements running in a single, continuous stream, but if you look closely at it, you should be able to see each of the RSA parameter values used. The encryption method uses only the modulus and exponent elements.

04fig04.jpgFigure 4-4. The SavingKeysAsXml example program.

InformIT Promotional Mailings & Special Offers

I would like to receive exclusive offers and hear about products from InformIT and its family of brands. I can unsubscribe at any time.

Overview


Pearson Education, Inc., 221 River Street, Hoboken, New Jersey 07030, (Pearson) presents this site to provide information about products and services that can be purchased through this site.

This privacy notice provides an overview of our commitment to privacy and describes how we collect, protect, use and share personal information collected through this site. Please note that other Pearson websites and online products and services have their own separate privacy policies.

Collection and Use of Information


To conduct business and deliver products and services, Pearson collects and uses personal information in several ways in connection with this site, including:

Questions and Inquiries

For inquiries and questions, we collect the inquiry or question, together with name, contact details (email address, phone number and mailing address) and any other additional information voluntarily submitted to us through a Contact Us form or an email. We use this information to address the inquiry and respond to the question.

Online Store

For orders and purchases placed through our online store on this site, we collect order details, name, institution name and address (if applicable), email address, phone number, shipping and billing addresses, credit/debit card information, shipping options and any instructions. We use this information to complete transactions, fulfill orders, communicate with individuals placing orders or visiting the online store, and for related purposes.

Surveys

Pearson may offer opportunities to provide feedback or participate in surveys, including surveys evaluating Pearson products, services or sites. Participation is voluntary. Pearson collects information requested in the survey questions and uses the information to evaluate, support, maintain and improve products, services or sites, develop new products and services, conduct educational research and for other purposes specified in the survey.

Contests and Drawings

Occasionally, we may sponsor a contest or drawing. Participation is optional. Pearson collects name, contact information and other information specified on the entry form for the contest or drawing to conduct the contest or drawing. Pearson may collect additional personal information from the winners of a contest or drawing in order to award the prize and for tax reporting purposes, as required by law.

Newsletters

If you have elected to receive email newsletters or promotional mailings and special offers but want to unsubscribe, simply email information@informit.com.

Service Announcements

On rare occasions it is necessary to send out a strictly service related announcement. For instance, if our service is temporarily suspended for maintenance we might send users an email. Generally, users may not opt-out of these communications, though they can deactivate their account information. However, these communications are not promotional in nature.

Customer Service

We communicate with users on a regular basis to provide requested services and in regard to issues relating to their account we reply via email or phone in accordance with the users' wishes when a user submits their information through our Contact Us form.

Other Collection and Use of Information


Application and System Logs

Pearson automatically collects log data to help ensure the delivery, availability and security of this site. Log data may include technical information about how a user or visitor connected to this site, such as browser type, type of computer/device, operating system, internet service provider and IP address. We use this information for support purposes and to monitor the health of the site, identify problems, improve service, detect unauthorized access and fraudulent activity, prevent and respond to security incidents and appropriately scale computing resources.

Web Analytics

Pearson may use third party web trend analytical services, including Google Analytics, to collect visitor information, such as IP addresses, browser types, referring pages, pages visited and time spent on a particular site. While these analytical services collect and report information on an anonymous basis, they may use cookies to gather web trend information. The information gathered may enable Pearson (but not the third party web trend services) to link information with application and system log data. Pearson uses this information for system administration and to identify problems, improve service, detect unauthorized access and fraudulent activity, prevent and respond to security incidents, appropriately scale computing resources and otherwise support and deliver this site and its services.

Cookies and Related Technologies

This site uses cookies and similar technologies to personalize content, measure traffic patterns, control security, track use and access of information on this site, and provide interest-based messages and advertising. Users can manage and block the use of cookies through their browser. Disabling or blocking certain cookies may limit the functionality of this site.

Do Not Track

This site currently does not respond to Do Not Track signals.

Security


Pearson uses appropriate physical, administrative and technical security measures to protect personal information from unauthorized access, use and disclosure.

Children


This site is not directed to children under the age of 13.

Marketing


Pearson may send or direct marketing communications to users, provided that

  • Pearson will not use personal information collected or processed as a K-12 school service provider for the purpose of directed or targeted advertising.
  • Such marketing is consistent with applicable law and Pearson's legal obligations.
  • Pearson will not knowingly direct or send marketing communications to an individual who has expressed a preference not to receive marketing.
  • Where required by applicable law, express or implied consent to marketing exists and has not been withdrawn.

Pearson may provide personal information to a third party service provider on a restricted basis to provide marketing solely on behalf of Pearson or an affiliate or customer for whom Pearson is a service provider. Marketing preferences may be changed at any time.

Correcting/Updating Personal Information


If a user's personally identifiable information changes (such as your postal address or email address), we provide a way to correct or update that user's personal data provided to us. This can be done on the Account page. If a user no longer desires our service and desires to delete his or her account, please contact us at customer-service@informit.com and we will process the deletion of a user's account.

Choice/Opt-out


Users can always make an informed choice as to whether they should proceed with certain services offered by InformIT. If you choose to remove yourself from our mailing list(s) simply visit the following page and uncheck any communication you no longer want to receive: www.informit.com/u.aspx.

Sale of Personal Information


Pearson does not rent or sell personal information in exchange for any payment of money.

While Pearson does not sell personal information, as defined in Nevada law, Nevada residents may email a request for no sale of their personal information to NevadaDesignatedRequest@pearson.com.

Supplemental Privacy Statement for California Residents


California residents should read our Supplemental privacy statement for California residents in conjunction with this Privacy Notice. The Supplemental privacy statement for California residents explains Pearson's commitment to comply with California law and applies to personal information of California residents collected in connection with this site and the Services.

Sharing and Disclosure


Pearson may disclose personal information, as follows:

  • As required by law.
  • With the consent of the individual (or their parent, if the individual is a minor)
  • In response to a subpoena, court order or legal process, to the extent permitted or required by law
  • To protect the security and safety of individuals, data, assets and systems, consistent with applicable law
  • In connection the sale, joint venture or other transfer of some or all of its company or assets, subject to the provisions of this Privacy Notice
  • To investigate or address actual or suspected fraud or other illegal activities
  • To exercise its legal rights, including enforcement of the Terms of Use for this site or another contract
  • To affiliated Pearson companies and other companies and organizations who perform work for Pearson and are obligated to protect the privacy of personal information consistent with this Privacy Notice
  • To a school, organization, company or government agency, where Pearson collects or processes the personal information in a school setting or on behalf of such organization, company or government agency.

Links


This web site contains links to other sites. Please be aware that we are not responsible for the privacy practices of such other sites. We encourage our users to be aware when they leave our site and to read the privacy statements of each and every web site that collects Personal Information. This privacy statement applies solely to information collected by this web site.

Requests and Contact


Please contact us about this Privacy Notice or if you have any requests or questions relating to the privacy of your personal information.

Changes to this Privacy Notice


We may revise this Privacy Notice through an updated posting. We will identify the effective date of the revision in the posting. Often, updates are made to provide greater clarity or to comply with changes in regulatory requirements. If the updates involve material changes to the collection, protection, use or disclosure of Personal Information, Pearson will provide notice of the change through a conspicuous notice on this site or other appropriate way. Continued use of the site after the effective date of a posted revision evidences acceptance. Please contact us if you have questions or concerns about the Privacy Notice or any objection to any revisions.

Last Update: November 17, 2020