SECURITY

Programming .NET Security : Extending the .NET Framework (part 2) - Defining the Key Exchange Deformatter

4/18/2011 11:32:34 AM

3. Defining the Key Exchange Deformatter

To complete the ElGamal implementation, define the ElGamalOAEPKeyExchangeDeformatter class, which decrypts the exchange data; this class extends the AsymmetricKeyExchangeDeformatter class:

using System.Security.Cryptography;
using System.IO;
using System;

public class ElGamalOAEPKeyExchangeDeformatter : AsymmetricKeyExchangeDeformatter {
private ElGamalManaged o_algorithm;
private PKCS1MaskGenerationMethod o_mask_generator;


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. 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:

    public override string Parameters {
get {
return o_algorithm.ToXmlString(true);
}
set {
o_algorithm.FromXmlString(value);
}
}

public override byte[] DecryptKeyExchange(byte[] p_byte) {
// decrypt the ciphertext
byte[] x_padded = o_algorithm.DecryptData(p_byte);
// remove the OAEP padding
byte[] x_plaintext = RestoreOAEPPaddedData(x_padded);
// return the ciphertext
return x_plaintext;
}

The remaining methods in this class are responsible for removing the OAEP formatting, which is outside the scope of this book:

    // the lHash value which is the preamble to an OAEP block
private byte[] o_lhash
= new BigInteger("da39a3ee5e6b4b0d3255bfef95601890afd80709", 16).getBytes( );

private byte[] RestoreOAEPPaddedData(byte[] p_data) {
// create a memory stream to hold the padded data
MemoryStream x_stream = new MemoryStream( );

// define K
int x_K = o_algorithm.KeySize/8 -1;

// determine how many complete blocks there are
int x_blocks = p_data.Length / x_K;

// run through and process the blocks blocks
byte[] x_block;
for (int i = 0; i < x_blocks; i++) {
x_block = RestoreSingleOAEPBlock(p_data, i * x_K, x_K, x_K);
x_stream.Write(x_block, 0, x_block.Length);
}

// return the padded data
return x_stream.ToArray( );
}

private byte[] RestoreSingleOAEPBlock(byte[] p_data, int p_offset,
int p_count, int p_K) {

// b. Separate the encoded message EM into a single octet Y,
// an octet string maskedSeed of length hLen, and an octet
// string maskedDB of length k - hLen - 1
// as EM = Y || maskedSeed || maskedDB
byte[] x_maskedSeed = new byte[o_lhash.Length];
Array.Copy(p_data, p_offset + 1, x_maskedSeed, 0, o_lhash.Length);
byte[] x_maskedDB = new byte[p_K - o_lhash.Length -1];
Array.Copy(p_data, p_offset + 1 + o_lhash.Length, x_maskedDB,
0, x_maskedDB.Length);

// c. Let seedMask = MGF (maskedDB, hLen).
byte[] x_seedMask
= o_mask_generator.GenerateMask(x_maskedDB, o_lhash.Length);

// d. Let seed = maskedSeed XOR seedMask
byte[] x_seed = (new BigInteger(x_maskedSeed)
^ new BigInteger(x_seedMask)).getBytes( );

// e. Let dbMask = MGF (seed, k - hLen - 1).
byte[] x_dbMask
= o_mask_generator.GenerateMask(x_seed, p_K - o_lhash.Length -1);

// f. Let DB = maskedDB XOR dbMask.
byte[] x_DB = (new BigInteger(x_maskedDB)
^ new BigInteger(x_dbMask)).getBytes( );

// g. Separate DB into an octet string lHash' of length hLen, a
// (possibly empty) padding string PS consisting of octets with
// hexadecimal value 0x00, and a message M as
// DB = lHash' || PS || 0x01 || M .
// If there is no octet with hexadecimal value 0x01 to separate PS from M,
// if lHash does not equal lHash', or if Y is nonzero,
// output "decryption error" and stop.
for (int i = 0; i < o_lhash.Length; i++) {
if (x_DB[i] != o_lhash[i]) {
throw new CryptographicException("Decryption Error");
}
}
if (p_data[0] != 0) {
throw new CryptographicException("Decryption Error");
}
// find the index representing the start of M
int x_index = -1;
for (int i = o_lhash.Length; i < x_DB.Length; i++) {
if (x_DB[i] == 0x01) {
// the next index is the start of M
x_index = i + 1;
break;
} else if (x_DB[i] != (byte)0x00) {
throw new CryptographicException("Decryption Error");
}
}
if (x_index == -1) {
throw new CryptographicException("Decryption Error");
}

// extract and return M
byte[] x_message = new byte[x_DB.Length - x_index];
Array.Copy(x_DB, x_index, x_message, 0, x_message.Length);
return x_message;
}

}

Other  
  •  Programming .NET Security : Programming Cryptographic Keys (part 3) - Key Exchange Formatting
  •  Programming .NET Security : Programming Cryptographic Keys (part 2) - Using Key Persistence
  •  Programming .NET Security : Programming Cryptographic Keys (part 1) - Creating Keys
  •  Deploying a Windows Server 2008 R2 Network Policy Server
  •  Understanding Network Access Protection (NAP) in Windows Server 2008 R2
  •  Programming .NET Security : Cryptographic Keys Explained
  •  Windows Server 2008 : Transport-Level Security - Using IPSec Encryption with Windows Server 2008 R2
  •  Windows Server 2008 : Transport-Level Security - Active Directory Rights Management Services
  •  Understanding Active Directory Certificate Services (AD CS) in Windows Server 2008 R2
  •  Deploying a Public Key Infrastructure with Windows Server 2008 R2
  •  
    Top 10
    Review : Sigma 24mm f/1.4 DG HSM Art
    Review : Canon EF11-24mm f/4L USM
    Review : Creative Sound Blaster Roar 2
    Review : Philips Fidelio M2L
    Review : Alienware 17 - Dell's Alienware laptops
    Review Smartwatch : Wellograph
    Review : Xiaomi Redmi 2
    Extending LINQ to Objects : Writing a Single Element Operator (part 2) - Building the RandomElement Operator
    Extending LINQ to Objects : Writing a Single Element Operator (part 1) - Building Our Own Last Operator
    3 Tips for Maintaining Your Cell Phone Battery (part 2) - Discharge Smart, Use Smart
    REVIEW
    - First look: Apple Watch

    - 3 Tips for Maintaining Your Cell Phone Battery (part 1)

    - 3 Tips for Maintaining Your Cell Phone Battery (part 2)
    VIDEO TUTORIAL
    - How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 1)

    - How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 2)

    - How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 3)
    Popular Tags
    Microsoft Access Microsoft Excel Microsoft OneNote Microsoft PowerPoint Microsoft Project Microsoft Visio Microsoft Word Active Directory Biztalk Exchange Server Microsoft LynC Server Microsoft Dynamic Sharepoint Sql Server Windows Server 2008 Windows Server 2012 Windows 7 Windows 8 Adobe Indesign Adobe Flash Professional Dreamweaver Adobe Illustrator Adobe After Effects Adobe Photoshop Adobe Fireworks Adobe Flash Catalyst Corel Painter X CorelDRAW X5 CorelDraw 10 QuarkXPress 8 windows Phone 7 windows Phone 8