Статьи

Как использовать ECC с OpenJDK

Каждый, кто когда-либо пытался использовать Elliptic Curve Cryptography (ECC) в Java с OpenJDK, был либо вынужден использовать Bouncy Castle, либо возиться с поставщиком SunEC . Поставщик SunEC предлагает следующие алгоритмы в соответствии с документацией (цитата):

AlgorithmParameters ЕС
KeyAgreement ECDH
KeyFactory ЕС
KeyPairGenerator ЕС
Signature NONEwithECDSA
SHA1withECDSA
SHA256withECDSA
SHA384withECDSA
SHA512withECDSA

К сожалению, этот провайдер не поставляется с OpenJDK. Но любой, кто действительно хотел бы попробовать встроенную функциональность Java ECC, возможно, попытается просто добавить sunec.jar (который содержит провайдера) в папку jre / lib / ext /. Но, пытаясь использовать провайдера, эти парни наверняка потрясут глаза. Все по-другому, чем кажется на первый взгляд …

Давайте предположим, что мы добавили библиотеку в правильную папку, наш OpenJDK заметил это, и мы могли бы успешно скомпилировать следующий код без каких-либо исключений:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
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 - [email protected]
 * @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());
        }
    }
 
}

Если мы наконец запустим его с OpenJDK (версия Java 1.7.0_25), мы получим следующий вывод:

1
2
KeyFactory: EC
AlgorithmParameters: EC

Вот Это Да! Это не очень полезный поставщик … Где обещанные алгоритмы? Давайте попробуем запустить код, просто для удовольствия, с Oracle JDK :

1
2
3
4
5
6
7
8
9
KeyFactory: EC
AlgorithmParameters: EC
Signature: NONEwithECDSA
Signature: SHA1withECDSA
Signature: SHA256withECDSA
Signature: SHA384withECDSA
Signature: SHA512withECDSA
KeyPairGenerator: EC
KeyAgreement: ECDH

Сюрприз Сюрприз! Это тот момент, когда вы начинаете тереть глаза! Вот алгоритмы, но почему они доступны только при использовании Oracle JDK?

Причина этого скрыта в коде провайдера. Следующие строки взяты из sun.security.ec.SunEC :

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
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));
    }
}

Кроме того, после добавления некоторых записей в список в классе SunECEntries можно найти следующее:

1
2
3
4
5
6
7
/*
 * Register the algorithms below only when the full ECC implementation
 * is available
 */
if (!useFullImplementation) {
    return;
}

Хорошо, это объясняет поведение. Алгоритмы присутствуют только в том случае, если собственная библиотека может быть успешно загружена (libsunec.so или sunec.dll на компьютерах с Windows). Эта библиотека явно отсутствует в нашем случае (поскольку мы скопировали только файл sunec.jar).

К сожалению, если бы мы прочитали документацию поставщика, мы бы знали об этом:

«[…] Классы Java упакованы в подписанный sunec.jar в каталоге расширений JRE, а функции C ++ и C упакованы в libsunec.so или sunec.dll в каталоге собственных библиотек JRE. Если собственная библиотека отсутствует, тогда этот поставщик регистрируется с поддержкой меньшего количества алгоритмов ECC (KeyPairGenerator, Signature и KeyAgreement опущены) ».

К сожалению, это был наш собственный поспешный интерес к действию, который стоил нам драгоценного времени нашей жизни разработчиков. Уберите: чтение JavaDocs иногда очень полезно … (но не так познавательно, как кропотливая отладка).

Ссылка: Как использовать ECC с OpenJDK от нашего партнера по JCG Кристофера Мейера из блога по безопасности Java и связанным темам .