Core Java

How to use ECC with OpenJDK

Everyone who ever tried to use Elliptic Curve Cryptography (ECC) in Java with an OpenJDK was either forced to use Bouncy Castle or fumble with the SunEC provider. The SunEC provider offers the following algorithms according to the documentation (quote):

AlgorithmParametersEC
KeyAgreementECDH
KeyFactoryEC
KeyPairGeneratorEC
SignatureNONEwithECDSA
SHA1withECDSA
SHA256withECDSA
SHA384withECDSA
SHA512withECDSA

Unfortunately, this provider is not shipped with OpenJDK. But anyone who really would like to try the Java builtin ECC functionility would possibly try to simply add the sunec.jar (which contains the provider) to the jre/lib/ext/ folder. But, when trying to use the provider these guys will definitely rub their eyes in amazement. Things are different than they seem at first…

Let’s assume we added the library to the correct folder, our OpenJDK notices it and we could successfully compile the following code without any exceptions:

package eccprovidertest;

import java.security.Provider;
import java.security.Provider.Service;
import java.security.Security;
import sun.security.ec.SunEC;

/**
 * ECC Provider Test.
 * @author  Christopher Meyer - christopher.meyer@rub.de
 * @version 0.1

 * Oct 23, 2013
 */
public class ECCProviderTest {

    /**
     * @param args the command line arguments
     */
    public static void main(final String[] args) {
        Provider sunEC = new SunEC();
        Security.addProvider(sunEC);
        for(Service service : sunEC.getServices()) {
            System.out.println(service.getType() + ": " 
                    + service.getAlgorithm());
        }
    }

}

If we finally run it with an OpenJDK (java version “1.7.0_25”) we get the following output:

KeyFactory: EC
AlgorithmParameters: EC

Wow! This is not a very useful provider….. Where are the promised algorithms? Let’s try to run the code, just for fun, with the Oracle JDK:

KeyFactory: EC
AlgorithmParameters: EC
Signature: NONEwithECDSA
Signature: SHA1withECDSA
Signature: SHA256withECDSA
Signature: SHA384withECDSA
Signature: SHA512withECDSA
KeyPairGenerator: EC
KeyAgreement: ECDH

Surprise, surprise! That’s the moment when you start rubbing your eyes! Here are the algorithms, but why are they only available when using the Oracle JDK?

The reason for this is hidden in the provider’s code. The following lines are taken from sun.security.ec.SunEC:

private static final long serialVersionUID = -2279741672933606418L;

// flag indicating whether the full EC implementation is present
// (when native library is absent then fewer EC algorithms are available)
private static boolean useFullImplementation = true;
static {
    try {
        AccessController.doPrivileged(new PrivilegedAction() {
            public Void run() {
               System.loadLibrary("sunec"); // check for native library
               return null;
            }
        });
    } catch (UnsatisfiedLinkError e) {
        useFullImplementation = false;
    }
}

public SunEC() {
    super("SunEC", 1.7d, "Sun Elliptic Curve provider (EC, ECDSA, ECDH)");

    // if there is no security manager installed, put directly into
    // the provider. Otherwise, create a temporary map and use a
    // doPrivileged() call at the end to transfer the contents
    if (System.getSecurityManager() == null) {
        SunECEntries.putEntries(this, useFullImplementation);
    } else {
        Map<Object, Object> map = new HashMap<Object, Object>();
        SunECEntries.putEntries(map, useFullImplementation);
        AccessController.doPrivileged(new PutAllAction(this, map));
    }
}

Additionally, the following can be found in SunECEntries class, after some entries have been added to the list:

/*
 * Register the algorithms below only when the full ECC implementation
 * is available
 */
if (!useFullImplementation) {
    return;
}

Ok, this explains the behaviour. The algorithms are only present if a native library could be successfully loaded (either libsunec.so or sunec.dll on Windows machines). This library is obviously missing in our case (since we only copied the sunec.jar file).

Unfortunately, if we had read the provider documentation we would know about that:

“[…] The Java classes are packaged into the signed sunec.jar in the JRE extensions directory and the C++ and C functions are packaged into libsunec.so or sunec.dll in the JRE native libraries directory. If the native library is not present then this provider is registered with support for fewer ECC algorithms (KeyPairGenerator, Signature and KeyAgreement are omitted).”

Unfortunately, it was our own, hasty zest for action which has cost us valuable time of our developer-life. Take away: Reading JavaDocs is sometimes really helpful….(, but not as educative as the painstaking debugging).
 

Reference: How to use ECC with OpenJDK from our JCG partner Christopher Meyer at the Java security and related topics blog.

Christopher Meyer

Chris works as a researcher and is eagerly looking for bugs in SSL/TLS, the Java platform and various applications. In addition, he is primarily interested in secure coding and exploiting coding mistakes.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button