17.3 Extending the .NET Framework

In the following sections, we complete our implementation of the
ElGamal algorithm by creating the key exchange formatter and
deformatter classes. We have only provided a C# implementation of the
ElGamal key exchange formatters. Like almost all encryption
algorithms, ElGamal relies on mathematical operations that are not
possible in Visual Basic .NET without creating additional support
functions to compensate for the limited numeric support the language
provides.

17.3.1 ElGamal Key Exchange Explained

To provide support for session key exchange, we must provide classes
that extend the AsymmetricExchangeFormatter and
AsymmetricExchangeDeformatter classes that we
discussed in the previous section. We have selected the OAEP
formatting scheme for our key exchange; we have listed the complete
code for our formatting classes, which naturally includes the details
of the OAEP scheme. We do not discuss the details of OAEP, and you
should refer to the PKCS #1 standard (which defines both the OAEP and
PKCS #1 v1.5 formatting schemes) for details.

17.3.2 Defining the Key Exchange Formatter

We begin by
defining
ElGamalOAEPKeyExchangeFormatter, which is our
formatter class, extending the
AsymmetricKeyExchangeFormatter class that we
discussed in the previous section:

The constructor creates an instance of the ElGamal implementation
class, ElGamalManaged. As you see in the
SetKey method, you can import the keys from any
implementation class that extends the abstract
ElGamal class using the common parameter import
and export methods. The other instance variables are related to the
OAEP formatting process:

The Parameters property returns the parameters of
the public key that will be used to encrypt the session key; we
create the result by using the ToXmlString method
defined in the AsymmetricAlgorithm class (see
Chapter 15 for details):

The SetKey method allows the user to specify an
instance of the ElGamal algorithm that should be used for encryption;
if the class is not an instance of our abstract
ElGamal class, throw an exception; otherwise,
import the public key parameters into the ElGamal
instance created by the constructor:

public override void SetKey(AsymmetricAlgorithm p_key) {
// encure that we are dealing with an ElGamal algorithm
if (p_key is ElGamal) {
// export the key and push it into the algorithm
o_algorithm.ImportParameters(((ElGamal)p_key).ExportParameters(false));
} else {
// we can't continue because the algorithm
// is the one for this class
throw new ArgumentException("Key Algorithm is not ElGamal", "p_key");
}
}

The CreateKeyExchange method
is responsible for formatting the
session key and encrypting the result using the
ElGamal implementation class; there are two
overloaded versions of this method, but they are functionality
equivalent, because the differentiating argument is not currently
used by the .NET Framework:

The constructor creates an instance of the ElGamal implementation
class, ElGamalManaged. As you see in the
SetKey method, you can import the keys from any
implementation class that extends the abstract
ElGamal class using the common parameter import
and export methods. The other instance variables are related to the
OAEP formatting process:

public ElGamalOAEPKeyExchangeDeformatter( ) {
// create the instance of the algorithm
o_algorithm = new ElGamalManaged( );
// init the mask generator
o_mask_generator = new PKCS1MaskGenerationMethod( );
}
public override void SetKey(AsymmetricAlgorithm p_key) {
// encure that we are dealing with an ElGamal algorithm
if (p_key is ElGamal) {
// export the key and push it into the algorithm
o_algorithm.ImportParameters(((ElGamal)p_key).ExportParameters(true));
} else {
// we can't continue because the algorithm
// is the one for this class
throw new ArgumentException("Key Algorithm is not ElGamal", "p_key");
}
}

The Parameters property returns the parameters of
the private key that will be used to decrypt the exchange data;
create the result by using the ToXmlString method
defined in the AsymmetricAlgorithm class (see
Chapter 15 for details). Unlike the equivalent
property in the formatter class, the deformatter implementation must
also import the key to use through the Parameters
property, which you do through the FromXmlString
method: