This documentation is archived and is not being maintained.

AsymmetricAlgorithm Class

Updated: February 2009

Represents the abstract base class from which all implementations of asymmetric algorithms must inherit.

Namespace:  System.Security.Cryptography
Assembly:  mscorlib (in mscorlib.dll)

[ComVisibleAttribute(true)]
public ref class AsymmetricAlgorithm abstract : IDisposable

Asymmetric cryptographic algorithms, also known as public-key algorithms, require that both sender and receiver maintain a pair of related keys: a private key and a public key. Both keys are unique to the entity. The public key can be made available to anyone; this key is used for encoding data that is sent to a receiver. The private key must be kept private by the receiver; this key is used for decoding messages encoded using the receiver's public key. The RSACryptoServiceProvider class is an implementation of a public-key algorithm.

You can use public-key systems to form digital signatures. Digital signatures are used to help to protect the integrity of data. For example, to use a public-key system to digitally sign a message, the sender first applies a hash function to the message to create a message digest. The sender then encrypts the message digest with the sender's private key to create the sender's personal signature. Upon receiving the message and signature, the receiver decrypts the signature using the sender's public key to recover the message digest and hashes the message using the same hash algorithm that the sender used. If the message digest that the receiver computes matches the message digest received from the sender, the receiver can assume that the message was not altered while in transit. Note that anyone can verify a signature, because the sender's public key is common knowledge. This technique does not retain the secrecy of the message; for the message to be secret, it must also be encrypted.

The DSACryptoServiceProvider class is an implementation of a digital signature algorithm. You can also use RSACryptoServiceProvider to create and verify a digital signature.

The System.Security.Cryptography namespace provides concrete classes for RSA and DSA only.

The following code example demonstrates how to implement a custom asymmetric algorithm that is inherited from the AsymmetricAlgorithm class. To build the example, you must sign the assembly for the example with the strong name key file CustomCrypto.snk. To create the key file, open the Properties window for the example and select the Signing tab. Select the Sign the assembly check box, and create a new key file named CustomCrypto.snk. An additional class is provided to demonstrate how to use the custom class.

#using <System.Xml.dll>
#using <System.Security.dll>

using namespace System;
using namespace System::Xml;
using namespace System::Text;
using namespace System::Security::Cryptography;
using namespace System::Reflection;

[assembly: AssemblyKeyFile("CustomCrypto.snk")];
[assembly: AssemblyVersion("1.0.0.0")];
[assembly: CLSCompliant(true)];
namespace Contoso
{
    // Define a CustomCrypto class that inherits from the AsymmetricAlgorithm 
    // class. 
    public ref class CustomCrypto :
        public System::Security::Cryptography::AsymmetricAlgorithm
        {
            // Declare local member variables. 
        private:
            CspParameters^ cryptoServiceParameters;
            array<KeySizes^>^ customValidKeySizes;

            // Initialize a CustomCrypto with the default key size of 8. 
        public:
            CustomCrypto()
            {
                customValidKeySizes = 
                    gcnew array<KeySizes^>{gcnew KeySizes(8, 64, 8)};
                this->KeySize = 8;
            }

            // Initialize a CustomCrypto with the specified key size. 
        public:
            CustomCrypto(int keySize)
            {
                customValidKeySizes = 
                    gcnew array<KeySizes^>{gcnew KeySizes(8, 64, 8)};
                this->KeySize = keySize;
            }

            // Accessor function for keySizes member variable. 
        public:
            property array<KeySizes^>^ LegalKeySizes
            {
                virtual array<KeySizes^>^ get() override
                {
                    return (array<KeySizes^>^)customValidKeySizes->Clone();
                }
            }

            // Modify the KeySizeValue property inherited from the Asymmetric 
            // class. Prior to setting the value, ensure it falls within the 
            // range identified in the local keySizes member variable. 
        public:
            property int KeySize
            {
                virtual int get() override
                {
                    return KeySizeValue;
                }

                virtual void set(int value) override
                {
                    for (int i = 0; i < customValidKeySizes->Length; i++)
                    {
                        if (customValidKeySizes[i]->SkipSize == 0)
                        {
                            if (customValidKeySizes[i]->MinSize == value)
                            {
                                KeySizeValue = value;
                                return;
                            }
                        }
                        else
                        {
                            for (int j = customValidKeySizes[i]->MinSize;
                                j <= customValidKeySizes[i]->MaxSize;
                                j += customValidKeySizes[i]->SkipSize)
                            {
                                if (j == value)
                                {
                                    KeySizeValue = value;
                                    return;
                                }
                            }
                        }
                    }

                    // If the key does not fall within the range identified 
                    // in the keySizes member variable, throw an exception. 
                    throw gcnew CryptographicException("Invalid key size.");
                }
            }

            // Initialize the parameters with default values. 
        public:
            void InitializeParameters()
            {
                cryptoServiceParameters = gcnew CspParameters();
                cryptoServiceParameters->ProviderName = "Contoso";
                cryptoServiceParameters->KeyContainerName = "SecurityBin1";
                cryptoServiceParameters->KeyNumber = 1;
                cryptoServiceParameters->ProviderType = 2;
            }

            // Parse specified xmlString for values to populate the CspParams 
            // Expected XML schema: 
            //  <CustomCryptoKeyValue> 
            //      <ProviderName></ProviderName> 
            //      <KeyContainerName></KeyContainerName> 
            //      <KeyNumber></KeyNumber> 
            //      <ProviderType></ProviderType> 
            //  </CustomCryptoKeyValue> 
        public:
            virtual void FromXmlString(String^ xmlString) override 
            {
                if (xmlString != nullptr)
                {
                    XmlDocument^ document = gcnew XmlDocument();
                    document->LoadXml(xmlString);
                    XmlNode^ firstNode = document->FirstChild;
                    XmlNodeList^ nodeList;

                    // Assemble parameters from values in each XML element.
                    cryptoServiceParameters = gcnew CspParameters();

                    // KeyContainerName is optional.
                    nodeList = 
                        document->GetElementsByTagName("KeyContainerName");
                    if (nodeList->Count > 0)
                    {
                        cryptoServiceParameters->KeyContainerName =
                            nodeList->Item(0)->InnerText;
                    }

                    // KeyNumber is optional.
                    nodeList = document->GetElementsByTagName("KeyNumber");
                    if (nodeList->Count > 0)
                    {
                        cryptoServiceParameters->KeyNumber =
                            Int32::Parse(nodeList->Item(0)->InnerText);
                    }

                    // ProviderName is optional.
                    nodeList = document->GetElementsByTagName("ProviderName");
                    if (nodeList->Count > 0)
                    {
                        cryptoServiceParameters->ProviderName =
                            nodeList->Item(0)->InnerText;
                    }

                    // ProviderType is optional.
                    nodeList = document->GetElementsByTagName("ProviderType");
                    if (nodeList->Count > 0)
                    {
                        cryptoServiceParameters->ProviderType =
                            Int32::Parse(nodeList->Item(0)->InnerText);
                    }
                }
                else
                {
                    throw gcnew ArgumentNullException("xmlString");
                }
            }

            // Create an XML string representation of the parameters in the 
            // current customCrypto object. 
        public:
            virtual String^ ToXmlString(bool includePrivateParameters) override
            {
                String^ keyContainerName = "";
                String^ keyNumber = "";
                String^ providerName = "";
                String^ providerType = "";

                if (cryptoServiceParameters != nullptr)
                {
                    keyContainerName = 
                        cryptoServiceParameters->KeyContainerName;
                    keyNumber = cryptoServiceParameters->KeyNumber.ToString();
                    providerName = cryptoServiceParameters->ProviderName;
                    providerType = 
                        cryptoServiceParameters->ProviderType.ToString();
                }

                StringBuilder^ sb = gcnew StringBuilder();
                sb->Append("<CustomCryptoKeyValue>");

                sb->Append("<KeyContainerName>");
                sb->Append(keyContainerName);
                sb->Append("</KeyContainerName>");

                sb->Append("<KeyNumber>");
                sb->Append(keyNumber);
                sb->Append("</KeyNumber>");

                sb->Append("<ProviderName>");
                sb->Append(providerName);
                sb->Append("</ProviderName>");

                sb->Append("<ProviderType>");
                sb->Append(providerType);
                sb->Append("</ProviderType>");

                sb->Append("</CustomCryptoKeyValue>");
                return(sb->ToString());
            }

            // Return the name for the key exchange algorithm. 
        public:
            property String^ KeyExchangeAlgorithm 
            {
                virtual String^ get() override
                {
                    return "RSA-PKCS1-KeyEx";
                }
            }

            // Retrieves the name of the signature alogrithm. 
        public:
            property String^ SignatureAlgorithm
            {
                virtual String^ get() override
                {
                    return "http://www.w3.org/2000/09/xmldsig#rsa-sha1";
                }
            }

            // Required member for implementing the AsymmetricAlgorithm class. 
		protected:
			virtual ~CustomCrypto()
			{
			}

            // Call the Create method using the CustomCrypto assembly name. 
            // The create function attempts to create a CustomCrypto  
            // object using the assembly name. This functionality requires  
            // modification of the machine.config file. Add the following  
            // section to the configuration element and modify the values  
            // of the cryptoClass to reflect what isinstalled  
            // in your machines GAC. 
            //<mscorlib> 
            //  <cryptographySettings> 
            //    <cryptoNameMapping> 
            //      <cryptoClasses> 
            //        <cryptoClass CustomCrypto="Contoso.CustomCrypto, 
            //          CustomCrypto, 
            //          Culture=neutral, 
            //          PublicKeyToken=fdb9f9c4851028bf, 
            //          Version=1.0.1448.27640" /> 
            //      </cryptoClasses> 
            //      <nameEntry name="Contoso.CustomCrypto"  
            //         class="CustomCrypto" />
            //      <nameEntry name="CustomCrypto" class="CustomCrypto" />
            //    </cryptoNameMapping> 
            //  </cryptographySettings> 
            //</mscorlib> 

        public:
            static CustomCrypto^ Create() 
            {
                return Create("CustomCrypto");
            }

            // Create a CustomCrypto object by calling CrytoConfig's 
            // CreateFromName method and casting the type to CustomCrypto. 
            // The create function attempts to create a CustomCrypto object  
            // using the assembly name. This functionality requires  
            // modification of the machine.config file. Add the following  
            // section to the configuration element and modify the values  
            // of the cryptoClass to reflect what is installed  
            // in your machines GAC. 
            //<mscorlib> 
            // <cryptographySettings> 
            //   <cryptoNameMapping> 
            //     <cryptoClasses> 
            //       <cryptoClass CustomCrypto="Contoso.CustomCrypto, 
            //         CustomCrypto, 
            //         Culture=neutral, 
            //         PublicKeyToken=fdb9f9c4851028bf, 
            //         Version=1.0.1448.27640" /> 
            //     </cryptoClasses> 
            //     <nameEntry name="Contoso.CustomCrypto"  
            //        class="CustomCrypto" />
            //     <nameEntry name="CustomCrypto" class="CustomCrypto" />
            //    </cryptoNameMapping> 
            //  </cryptographySettings> 
            //</mscorlib> 

        public:
            static CustomCrypto^ Create(String^ algorithmName) 
            {
                return (CustomCrypto^) 
                    CryptoConfig::CreateFromName(algorithmName);
            }
        };
}
#using <System.Xml.dll>
#using <System.Security.dll>

using namespace System;
using namespace System::Xml;
using namespace System::Text;
using namespace System::Security::Cryptography;

// Display the properties of the specified CustomCrypto object to the 
// console. 
static void DisplayProperties(Contoso::CustomCrypto^ customCryptoAlgorithm)
{
    // Retrieve the class description for the customCrypto object.
    String^ classDescription = customCryptoAlgorithm->ToString();

    Console::WriteLine(classDescription);
    Console::WriteLine("KeyExchangeAlgorithm: {0}",
        customCryptoAlgorithm->KeyExchangeAlgorithm);
    Console::WriteLine("SignatureAlgorithm: {0}",
        customCryptoAlgorithm->SignatureAlgorithm);
    Console::WriteLine("KeySize: {0}",
        customCryptoAlgorithm->KeySize);
    Console::WriteLine("Parameters described in Xml format:");
    Console::WriteLine(customCryptoAlgorithm->ToXmlString(true));

    // Display the MinSize, MaxSize, and SkipSize properties of 
    // each KeySize item in the local keySizes member variable. 
    array<KeySizes^>^ legalKeySizes = customCryptoAlgorithm->LegalKeySizes;
    for (int i = 0; i < legalKeySizes->Length; i++)
    {
        Console::WriteLine(
            "Keysize{0} min, max, step: {1}, {2}, {3}, ", i,
            legalKeySizes[i]->MinSize,
            legalKeySizes[i]->MaxSize,
            legalKeySizes[i]->SkipSize);
    }
}

[STAThread]
int main()
{
    // Construct a CustomCrypto object and initialize its 
    // CspParameters.
    Contoso::CustomCrypto^ customCryptoAlgorithm = gcnew Contoso::CustomCrypto();
    customCryptoAlgorithm->InitializeParameters();

    // Display properties of the current customCrypto object.
    Console::WriteLine(
        "*** CustomCrypto created with default parameters:");
    DisplayProperties(customCryptoAlgorithm);

    // Release all the resources used by this instance of 
    // CustomCrypto.
    customCryptoAlgorithm->Clear();

    customCryptoAlgorithm = gcnew Contoso::CustomCrypto(64);
    // Create new parameters and set them by using the FromXmlString 
    // method.
    String^ parameterXml = "<CustomCryptoKeyValue>" +
        "<ProviderName>Contoso</ProviderName>" +
        "<KeyContainerName>SecurityBin2</KeyContainerName>" +
        "<KeyNumber>1</KeyNumber>" +
        "<ProviderType>2</ProviderType>" +
        "</CustomCryptoKeyValue>";
    customCryptoAlgorithm->FromXmlString(parameterXml);

    // Display the properties of a customCrypto object created with 
    // custom parameters.
    Console::WriteLine(
        "{0}*** CustomCrypto created with custom parameters:", Environment::NewLine);
    DisplayProperties(customCryptoAlgorithm);

    // Create an object by using the assembly name.
    Contoso::CustomCrypto^ cryptoFromAssembly =
        Contoso::CustomCrypto::Create("CustomCrypto");
    if (cryptoFromAssembly != nullptr)
    {
        Console::WriteLine("{0}*** Successfully created " +
            "CustomCrypto from the Create method.", Environment::NewLine);
        DisplayProperties(cryptoFromAssembly);
    }
    else
    {
        Console::WriteLine("Unable to create CustomCrypto from " +
            "the Create method.");
    }

    Console::WriteLine(
        "This sample completed successfully; press Enter to exit.");
    Console::ReadLine();
}

// 
// This sample produces the following output: 
// 
// *** CustomCrypto created with default parameters: 
// Contoso.vbCustomCrypto 
// KeyExchangeAlgorithm: RSA-PKCS1-KeyEx 
// SignatureAlgorithm: http://www.w3.org/2000/09/xmldsig#rsa-sha1 
// KeySize: 8 
// Parameters described in Xml format: 
// <CustomCryptoKeyValue><KeyContainerName>SecurityBin1</KeyContainerName> 
// <KeyNumber>1</KeyNumber><ProviderName>Contoso</ProviderName> 
// <ProviderType>2</ProviderType></CustomCryptoKeyValue> 
// Keysize0 min, max, step: 8, 64, 8, 
// 
// *** CustomCrypto created with custom parameters: 
// Contoso.vbCustomCrypto 
// KeyExchangeAlgorithm: RSA-PKCS1-KeyEx 
// SignatureAlgorithm: http://www.w3.org/2000/09/xmldsig#rsa-sha1 
// KeySize: 64 
// Parameters described in Xml format: 
// <CustomCryptoKeyValue><KeyContainerName>SecurityBin2</KeyContainerName> 
// <KeyNumber>1</KeyNumber><ProviderName>Contoso</ProviderName> 
// <ProviderType>2</ProviderType></CustomCryptoKeyValue> 
// Keysize0 min, max, step: 8, 64, 8, 
// Unable to create CustomCrypto from the Create method 
// This sample completed successfully; press Enter to exit.

Any public static (Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe.

Windows 7, Windows Vista, Windows XP SP2, Windows XP Media Center Edition, Windows XP Professional x64 Edition, Windows XP Starter Edition, Windows Server 2008 R2, Windows Server 2008, Windows Server 2003, Windows Server 2000 SP4, Windows Millennium Edition, Windows 98, Windows CE, Windows Mobile for Smartphone, Windows Mobile for Pocket PC

The .NET Framework and .NET Compact Framework do not support all versions of every platform. For a list of the supported versions, see .NET Framework System Requirements.

.NET Framework

Supported in: 3.5, 3.0, 2.0, 1.1, 1.0

.NET Compact Framework

Supported in: 3.5, 2.0

Date

History

Reason

February 2009

Added information about the key file to the Example section.

Customer feedback.

Show: