Каждый, кто когда-либо пытался использовать 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 - 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()); } }} |
Если мы наконец запустим его с OpenJDK (версия Java 1.7.0_25), мы получим следующий вывод:
|
1
2
|
KeyFactory: ECAlgorithmParameters: EC |
Вот Это Да! Это не очень полезный поставщик … Где обещанные алгоритмы? Давайте попробуем запустить код, просто для удовольствия, с Oracle JDK :
|
1
2
3
4
5
6
7
8
9
|
KeyFactory: ECAlgorithmParameters: ECSignature: NONEwithECDSASignature: SHA1withECDSASignature: SHA256withECDSASignature: SHA384withECDSASignature: SHA512withECDSAKeyPairGenerator: ECKeyAgreement: 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 иногда очень полезно … (но не так познавательно, как кропотливая отладка).