The ECCDH Key Exchange

  

One of the most common ways of passing ECC keys is to use a modified Diffie-Hellman using ECC ( ECCDH ) version. The idea is to pass a public key and then generate a shared secret key to use for a new public key. Just as in Diffie-Hellman, the key is produced from multiplication.

Understanding the ECC key exchange

The ECCDH public key algorithm depends on the calculation of an agreed-upon elliptic curve, the point on the curve as a starting point, deriving a random number for a private key, and sending other users the product of all these values. The receiving user , knowing the curve and starting point, can use the sender's product and derive a common product for both users to share as a key. The key agreement for ECCDH follows this sequence:

  • First User A and User B select the elliptic curve by choosing prime numbers p , a , and b that satisfy the elliptic curve group E p (a,b) . The elliptic curve equation is y 2 = x 3 + ax + b (mod p) .

    For example, p = 211 , a = 0 , and b = -4 create the elliptic curve group E 211 (0, -4) and the elliptic curve y 2 = x 3 - 4 .

  • User A and User B select a common (x,y) coordinate point P on the elliptic curve y 2 = x 3 - 4 that is less than p .

    For example, using x = 2 will generate y = 2 , so P(2,2) . The P point in this example is known as the generator or G in the Diffie-Hellman algorithm.

  • User A selects a random number, d , less than p , that will be multiplied by the point P to retrieve a multiple point Q on the curve, Q = dP .

    For the example d = 203, Q = (203)(2,2) = (130,203).

  • User A sends the public key Q to User B.

  • User B selects a random number, d , less than p that will be multiplied by the point P to retrieve a multiple of point Q on the curve, Q = dP .

    For the example d = 121, Q = (121)(2,2) = (115,48).

  • User B sends the public key Q to User A.

  • User A can calculate a shared key by computing S = dQ with Q received from B.

    For the example d = 203, S = (203)(115,48) = (161,169).

  • User B can calculate a shared key by computing S = dQ with Q received from A.

    For the example d = 121, S = (121)(130,203) = (161,169).

  • Both users now contain share and public keys.

Understanding the Service Provider Interface (SPI)

There are two main layers that a developer using the JDK 1.4 must completely understand: the Application Layer Interface (API) and the Service Provider Interface (SPI). The API is the interface that the developer uses to load up algorithms and protocols. The SPI layer loads up the appropriate algorithms and protocols based on the parameters passed in through the API. The service providers maintain information in properties files. If the properties files are not defined correctly, the appropriate service may not be loaded, or worse , it may be loaded with a corrupted service. A simple issue can be that the classpath is not set correctly to the appropriate providers.

Implementing the ECC key exchange as an SPI

To build a service provider module, there are exact classes, interfaces, and entries into the properties files that must be accomplished. Building an SPI interface is a very structured interface for the JDK 1.4.

The interface that most developers will actually have to understand is the java.security.Provider class. To implement an asymmetric key interface, the java.security.KeyFactory and java.security.KeyPairGenerator must be implemented and an association must be provided in the Provider class implementation. See Listing 5-2.

Listing 5-2: The ECCProvider class: The Provider class
start example
 package com.richware.chap05; import java.security.AccessController; import java.security.PrivilegedAction;     /**  * Class ECCProvider  * Description: This is a example of a  * simple ECC Provider  *  * Copyright:    Copyright (c) 2002 Wiley Publishing, Inc.  * @author Rich Helton <rhelton@richware.com>  * @version 1.0  * DISCLAIMER: Please refer to the disclaimer at the beginning of this book.  */ public final class ECCProvider extends java.security.Provider {     private static final String INFO = "Rich's provider for ECC";         public ECCProvider()     {         super("RichECC", 1.0, INFO);         AccessController.doPrivileged(new PrivilegedAction() {             public Object run()             {                 put("KeyFactory.ECC", "com.richware.chap05.ECCKeyFactory");                 put("KeyPairGenerator.ECC", "com.richware.chap05.ECCKeyPairGenerator");                 return null;             }         });     } } 
end example
 

Listing 5-2 associates the com.richware.chap05.ECCKeyFactory and the com.richware.chap05.ECCKeyPairGenerator . It returns these instances when the " ECC " is passed in as the type for the KeyFactory's and KeyPairGenerator's getInstance methods . The name of the service provider is " RichECC ", which is passed in the super class if a lookup is done by the service provider's name. The provider interface is supplied, but it will not be called unless the entry is added to the $JRE\lib\security\java.security file.

Listing 5-3 displays the added entry.

Listing 5-3: Adding the ECCProvider class
start example
 security.provider.1=sun.security.provider.Sun security.provider.2=com.sun.net.ssl.internal.ssl.Provider security.provider.3=com.sun.rsajca.Provider security.provider.4=com.sun.crypto.provider.SunJCE security.provider.5=sun.security.jgss.SunProvider security.provider.6=com.richware.chap05.ECCProvider 
end example
 

Listings 5-2 and 5-3 give an example of configuring a provider. The developer should be familiar with this exercise. The developer should also be familiar with the API for calling the classes and methods to generate the keys. Listing 5-4 gives an example implementation of interfacing with the KeyFactory and KeyPairGenerator .

Listing 5-4: The ECCSimpleApp class: The sample application
start example
 package com.richware.chap05; import java.util.*; import java.math.*; import java.security.*; import javax.crypto.spec.*;     /**  * Class ECCSimpleApp  * Description: This is a example of a  * simple ECC  *  * Copyright:    Copyright (c) 2002 Wiley Publishing, Inc.  * @author Rich Helton <rhelton@richware.com>  * @version 1.0   * DISCLAIMER: Please refer to the disclaimer at the beginning of this book.  */ public class ECCSimpleApp  {   /**    * Method main    * Description: The Main test driver    * @param args none    *    */   public static void main(String[] args)    {     try      {       System.out.println();       System.out.println(         "ECC letting the algorithm choose randoms**************");       KeyPairGenerator kpg =         KeyPairGenerator.getInstance("ECC");           /*        * A strong key uses 512 to 2048 bits        * the bits must be multiples of 64        */       System.out.println("Provider =" + kpg.getProvider());       kpg.initialize(512);       KeyPair kp = kpg.generateKeyPair();           /*        * Read the keys        * produced by the algorithm        */       System.out.println("Public Key ="                          + kp.getPublic().getEncoded());       System.out.println("Public Key Algorithm ="                          + kp.getPublic().getAlgorithm());       System.out.println("Public Key Format ="                          + kp.getPublic().getFormat());       System.out.println("Private Key ="                          + kp.getPrivate().getEncoded());       System.out.println("Private Key Algorithm ="                          + kp.getPrivate().getAlgorithm());       System.out.println("Private Key Format ="                          + kp.getPrivate().getFormat());           /*        * Initialize the KeyFactory for DSA        */       KeyFactory kfactory = KeyFactory.getInstance("ECC");           /*        * Create the DH public key spec        */       ECCPublicKeySpec kspec =         (ECCPublicKeySpec) kfactory           .getKeySpec(kp.getPublic(), ECCPublicKeySpec.class);           /*        * Print out public Public Q point public values        * to be sent to the other user        */       System.out.println("Public Key QY =" + kspec.getQY());       System.out.println("Public Key QX =" + kspec.getQX());     }         /*      * Catches      */     catch (java.security.NoSuchAlgorithmException ex)      {       ex.printStackTrace();     }     catch (Exception ex)      {       ex.printStackTrace();     }   } } 
end example
 

Listing 5-4 demonstrates initializing the ECC algorithm. The ECC algorithm needs to know the key size , and optionally the random generator. Like most algorithms, if the key size is not specified, it will default to 512-bit key size. The KeyFactory , ECCPublicKeySpec , and ECCPrivateKeySpec are used to pass key-specific parameters for initiation. The private key spec will be the d parameter, and the public key specifications will require the point for Q for x and y . These values were discussed earlier in this chapter.

The public key spec is needed to return the values of point Q in order to pass these values to the other user. Most implementations save the public key values to a file or a socket to pass them to the receiving user for developing a shared key. The key spec values are also useful for initializing the keys. The key spec values are extended for the java.security.spec.KeySpec interface.

The key specs are used to pass values to the actual keys, ECCPublicKey for an implementation of the public key and ECCPrivateKey for the private key. The public key is extended from the java.security. PublicKey interface. The private key is extended from the java.security.PrivateKey interface. The public key and private key interfaces mark the classes as serializable for saving key information and are used to identify in which class the key information is kept.

Other specifications in this implementation are the ECCParameterSpec and the ECCGenParameterSpec . Both of these spec classes are extended from the java.security.spec.AlgorithmParameterSpec interface. The ECCParameterSpec is used for passing cryptographic information between the keys in the generators and factories. The ECCGenParameterSpec is specific cryptographic information for generating the key pair. The ECCGenParameterSpec in the Listing 5-4 implementation contains the prime size p .

There are many benefits to using the API and SPI interfaces supplied by Java. By looking at the key and parameter spec, the parameters and high-level details of the algorithm can be understood without going into the minor details of the mathematics.

Listing 5-5 and Listing 5-6 show the ECCKeyFactory and ECCKeyPairGenerator classes, respectively.

Listing 5-5: The ECCKeyFactory class: The factory class
start example
 package com.richware.chap05; import java.security.*; import java.security.spec.*; import javax.crypto.interfaces.*; import javax.crypto.spec.*;     /**  * Class ECCKeyFactory  * Description: The factory class for   * building and retrieving   * keys based on spec.  *  * Copyright:    Copyright (c) 2002 Wiley Publishing, Inc.  * @author Rich Helton <rhelton@richware.com>  * @version 1.0    * DISCLAIMER: Please refer to the disclaimer at the beginning of this book.  */ public final class ECCKeyFactory extends KeyFactorySpi  {   /**    * Constructor ECCKeyFactory   */   public ECCKeyFactory() {}       /*    * Method engineGeneratePublic    * Description: Builds public key    * from spec info    */   protected PublicKey engineGeneratePublic(KeySpec keyspec)           throws InvalidKeySpecException    {     try      {       if (keyspec instanceof ECCPublicKeySpec)        {         ECCPublicKeySpec eccpublickeyspec =           (ECCPublicKeySpec) keyspec;         return new ECCPublicKey(eccpublickeyspec.getQY(),                                 eccpublickeyspec.getQX());       }       else        {         throw new InvalidKeySpecException(           "Inappropriate key specification");       }     }     /*      * Catches      */     catch (InvalidKeyException invalidkeyexception)      {       throw new InvalidKeySpecException(         "Inappropriate key specification");     }   }       /*    * Method engineGeneratePrivate    * Description: Builds private key    * from spec info    */   protected PrivateKey engineGeneratePrivate(KeySpec keyspec)           throws InvalidKeySpecException    {     try      {       if (keyspec instanceof DHPrivateKeySpec)        {         ECCPrivateKeySpec eccprivatekeyspec =           (ECCPrivateKeySpec) keyspec;         return new ECCPrivateKey(eccprivatekeyspec.getD());       }       else        {         throw new InvalidKeySpecException(           "Inappropriate key specification");       }     }     /*      * Catches      */     catch (InvalidKeyException invalidkeyexception)      {       throw new InvalidKeySpecException(         "Inappropriate key specification");     }   }       /*    * Method engineGetKeySpec    * Description: Gets the spec info    * based on key type    */   protected KeySpec engineGetKeySpec(Key key, Class class1)           throws InvalidKeySpecException    {     try      {       if (key instanceof ECCPublicKey)        {         Class class2 = Class           .forName("ECCPublicKeySpec");         if (class2.isAssignableFrom(class1))          {           ECCPublicKey     eccpublickey     =             (ECCPublicKey) key;           ECCParameterSpec eccparameterspec =             eccpublickey.getParams();           return new ECCPublicKeySpec(eccpublickey.getQY(),                                       eccparameterspec.getP());         }         else          {           throw new InvalidKeySpecException(             "Inappropriate key specification");         }       }       if (key instanceof ECCPrivateKey)        {         Class class3 = Class           .forName("ECCPrivateKeySpec");         if (class3.isAssignableFrom(class1))          {           ECCPrivateKey    eccprivatekey     =             (ECCPrivateKey) key;           ECCParameterSpec eccparameterspec1 =             eccprivatekey.getParams();           return new ECCPrivateKeySpec(eccprivatekey.getD());         }         else          {           throw new InvalidKeySpecException(             "Inappropriate key specification");         }       }       else        {         throw new InvalidKeySpecException(           "Inappropriate key type");       }     }     /*      * Catches      */     catch (ClassNotFoundException classnotfoundexception)      {       throw new InvalidKeySpecException(         "Unsupported key specification: "         + classnotfoundexception.getMessage());     }   }       protected Key engineTranslateKey(Key key)           throws InvalidKeyException    {     try      {       if (key instanceof ECCPublicKey)        {         if (key instanceof ECCPublicKey)          {           return key;         }         else          {           ECCPublicKeySpec eccpublickeyspec =             (ECCPublicKeySpec) engineGetKeySpec(key, ECCPublicKeySpec.class);           return engineGeneratePublic(eccpublickeyspec);         }       }       if (key instanceof ECCPrivateKey)        {         if (key instanceof ECCPrivateKey)          {           return key;         }         else          {           ECCPrivateKeySpec eccprivatekeyspec =             (ECCPrivateKeySpec) engineGetKeySpec(key, ECCPrivateKeySpec.class);           return engineGeneratePrivate(eccprivatekeyspec);         }       }       else        {         throw new InvalidKeyException("Wrong algorithm type");       }     }     /*      * Catches      */     catch (InvalidKeySpecException invalidkeyspecexception)      {       throw new InvalidKeyException("Cannot translate key");     }   } } 
end example
 
Tip  

For more of the code and references to sites, see the companion Web site to this book at www.wiley.com/extras . Here are a few links to get you started:

For cyptography and ECC information visit:

www.tcs.hut.fi/~helger/crypto/link/public/elliptic/

For information on security of elliptic curve cryptosystems visit:

www.certicom.com/research/wecc3.html

Listing 5-6: The ECCKeyPairGenerator class
start example
 package com.richware.chap05; import java.math.BigInteger; import java.security.*; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.InvalidParameterSpecException; import javax.crypto.spec.DHGenParameterSpec;     /**  * Class ECCKeyPairGenerator  * Description: The generator for the  * key pair for ECC   *  * Copyright:    Copyright (c) 2002 Wiley Publishing, Inc.  * @author Rich Helton <rhelton@richware.com>  * @version 1.0    * DISCLAIMER: Please refer to the disclaimer at the beginning of this book.  */ public final class ECCKeyPairGenerator         extends KeyPairGeneratorSpi  {   private BigInteger   a;   private BigInteger   b;   private BigInteger   c;   private BigInteger   d;   private int          e;   private int          f;   private SecureRandom g;       /**    * Constructor ECCKeyPairGenerator    */   public ECCKeyPairGenerator()    {     e = 1024;   }       /**    * Method initialize    * Description: Initialiazes the    * key bit size and random generator    * @param i    * @param securerandom    *    */   public void initialize(int i, SecureRandom securerandom)    {     if ((i < 512)  (i > 1024)  (i % 64 != 0))      {       throw new InvalidParameterException(         "Keysize must be multiple of 64, and can only range from 512 to 1024 (inclusive)");     }     else      {       e = i;       f = 0;       g = securerandom;       return;     }   }       /**    * Method initialize    * Description: Initialiazes the    * key bit size and keys based on the    * algorithm spec    * @param algorithmparameterspec    * @param securerandom    *    * @throws InvalidAlgorithmParameterException    *    */   public void initialize(           AlgorithmParameterSpec algorithmparameterspec, SecureRandom securerandom)             throws InvalidAlgorithmParameterException    {     if (!(algorithmparameterspec instanceof ECCParameterSpec))      {       throw new InvalidAlgorithmParameterException(         "Inappropriate parameter type");     }     c = ((ECCParameterSpec) algorithmparameterspec).getP();     e = c.bitLength();     if ((e < 512)  (e > 1024)  (e % 64 != 0))      {       throw new InvalidAlgorithmParameterException(         "Prime size must be multiple of 64, and can only range from 512 to 1024 (inclusive)");     }     d = ((ECCParameterSpec) algorithmparameterspec).getG();     f = ((ECCParameterSpec) algorithmparameterspec).getL();     g = securerandom;     if ((f != 0) && (f >= e))      {       throw new InvalidAlgorithmParameterException(         "Exponent size must be less than modulus size");     }     else      {       return;     }   }       /**    * Method generateKeyPair    * Description: Generates the key pair    * @return the Key pair generated    *    */   public KeyPair generateKeyPair()    {     KeyPair keypair = null;     if (f == 0)      {       f = e - 1;     }     if (g == null)      {       g = new SecureRandom();     }     try      {       if ((c == null)  (d == null))        {         ECCGenParameterSpec   eccgenparameterspec   =           new ECCGenParameterSpec(e);         ECCParameterGenerator eccparametergenerator =           new ECCParameterGenerator();         eccparametergenerator.engineInit(eccgenparameterspec,                                          null);         AlgorithmParameters algorithmparameters =           eccparametergenerator.engineGenerateParameters();         ECCParameterSpec    ECCParameterSpec    =           (ECCParameterSpec) algorithmparameters             .getParameterSpec(ECCParameterSpec.class);         c = ECCParameterSpec.getP();         d = ECCParameterSpec.getG();       }       b = new BigInteger(f, g);       a = d.modPow(b, c);       ECCPublicKey  eccpublickey  = new ECCPublicKey(a, c, d,                                       f);       ECCPrivateKey eccprivatekey = new ECCPrivateKey(b, c, d,                                       f);       keypair = new KeyPair(eccpublickey, eccprivatekey);     }     /*      * Catches      */     catch (InvalidAlgorithmParameterException invalidalgorithmparameterexception)      {       throw new RuntimeException(         invalidalgorithmparameterexception.getMessage());     }     catch (InvalidParameterSpecException invalidparameterspecexception)      {       throw new RuntimeException(invalidparameterspecexception         .getMessage());     }     catch (InvalidKeyException invalidkeyexception)      {       throw new RuntimeException(invalidkeyexception         .getMessage());     }     return keypair;   } } 
end example
 
  


Java Security Solutions
Java Security Solutions
ISBN: 0764549286
EAN: 2147483647
Year: 2001
Pages: 222

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net