Каждый, кто когда-либо пытался использовать 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 иногда очень полезно … (но не так познавательно, как кропотливая отладка).