Asymmetric cryptography also known as public-key encryption uses a public/private key pair to encrypt and decrypt data. Public key in asymmetric cryptography is available to public but the private key must be protected with the user, else it can be used to decrypt data.
In .NET, the RSACryptoServiceProvider and DSACryptoServiceProvider classes are used for asymmetric encryption. A random public/private key pair is generated when a new instance of the class is created.
- RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
Once keys are generated, we can use ToXmlString or ExportParameters method to read the keys.
The ToXmlString method returns key information in XML as a string. The method takes a Boolean parameter. If passed false, it returns public key only. If passed true, it returns both private and public pair.
The following code snippet returns a public key.
- string str = RSA.ToXmlString(false);
The public key looks like the following with a Modulus value and an Exponent value.
- <RSAKeyValue>
- <Modulus>lF1Yof6FXaY9M/StHwPC1voW5K5JOqSu8BXndS4WH06L9mOfrNI9Et0cRaHjiYd2bQNFZB9+ AZmN4ODc36DgVPqQqYY2tbH+9UY0hcdi+WnDuUZe7sgvWKfGwBKTcy7g8uUAzpTWEP1W0FqeMunmXljD8Iouoqp5oHtTW1GHIlE=</Modulus>
- <Exponent>AQAB</Exponent>
- </RSAKeyValue>
When a true value is passed.
- string str = RSA.ToXmlString(true);
The output looks like the following that has both public and private keys.
- <RSAKeyValue>
- <Modulus>tMvvUeHhggKAVex8JzYKXYQ32HVmr05PdtT1KV3kTkKE26jO/9IVmg+bWwxR1vuMzmY7spwguSJQsnjutJXamH0 mblNgYHmWwhyhJMSTtnZp57VDNNedjCFQnLOn211yk/PpCQHEiDDvt84hnmcdXNBlfZfkQzQ+UO/elhP5NH0=</Modulus>
- <Exponent>AQAB</Exponent>
- <P>22SSx3JpSqYVUWuxiSKwmh/8RDDcgDvq8l+4dMlQ/F+BJhthTQ3UJGupWaxiJyXX95AYAJIJJvWVvmvI7tqbxw==</P><Q>0va2WFy0oUwX4eJtZElRbot9TOrwGcqI64rMAYjvxl/mayCRXf0ypwKofKWOsmjK/pX0xWaqnFWB/NdLFt4Fmw==</Q><DP>VbIYPz2qcRUkmJQnWbiqINnDkONBDfnZkOjgxQVp09p+OONTA2UWa09+a9+Qy1fV3wZyya5BUu10m1fAucO8Ow==</DP>
- <DQ>Lm8hOZfGJk6SXySwgUdmBhfrz3dSu8qJkpatSpUyeY54MBIuDOsDMCF0pmLmYryQGbM1+hEb8mcbwmQ84d6iiw==</DQ>
- <InverseQ>L67OLIIK+M3OF1nxSHTjZ+Kv/hwOHJPvdHHSuh9VEmw93kPGn6Qt6GudEreFb6xlFsuR6UM19LUIweapgaUagQ==</InverseQ>
- <D>YbaGlZ6bHoTzj3zMbPTMDVbUR+zLnpuYXwUhq0XPimxxGbbWiXSlsCoXMNIruSEjLLocMaAoH2bobkzl1jvXdAI30NdZ/rpG5SRl dpaeIundLfHkSnZfHwHuP9OGXJSXmbmLCrO8dq7BjLauS4JiTRgjiXoq8c995MEF+vhw9hE=</D>
- </RSAKeyValue>
The ExportParameters method returns an RSAParameters structure that holds the key information in separate fields.
-
- RSAParameters RSAKeyInfo = RSA.ExportParameters(true);
- Console.WriteLine($"Modulus: {System.Text.Encoding.UTF8.GetString(RSAKeyInfo.Modulus)}");
- Console.WriteLine($"Exponent: {System.Text.Encoding.UTF8.GetString(RSAKeyInfo.Exponent)}");
- Console.WriteLine($"P: {System.Text.Encoding.UTF8.GetString(RSAKeyInfo.P)}");
- Console.WriteLine($"Q: {System.Text.Encoding.UTF8.GetString(RSAKeyInfo.Q)}");
- Console.WriteLine($"DP: {System.Text.Encoding.UTF8.GetString(RSAKeyInfo.DP)}");
- Console.WriteLine($"DQ: {System.Text.Encoding.UTF8.GetString(RSAKeyInfo.DQ)}");
Here is a complete working example.
- using System;
- using System.Security.Cryptography;
- class PrivatePublicKeyGenerator {
- static void Main(string[] args) {
-
- RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
-
- string str = RSA.ToXmlString(true);
- Console.WriteLine(str);
-
- RSAParameters RSAKeyInfo = RSA.ExportParameters(true);
- Console.WriteLine($ "Modulus: {System.Text.Encoding.UTF8.GetString(RSAKeyInfo.Modulus)}");
- Console.WriteLine($ "Exponent: {System.Text.Encoding.UTF8.GetString(RSAKeyInfo.Exponent)}");
- Console.WriteLine($ "P: {System.Text.Encoding.UTF8.GetString(RSAKeyInfo.P)}");
- Console.WriteLine($ "Q: {System.Text.Encoding.UTF8.GetString(RSAKeyInfo.Q)}");
- Console.WriteLine($ "DP: {System.Text.Encoding.UTF8.GetString(RSAKeyInfo.DP)}");
- Console.WriteLine($ "DQ: {System.Text.Encoding.UTF8.GetString(RSAKeyInfo.DQ)}");
- Console.ReadKey();
- }
- }