[追記あり] Java SE 6に
Bouncy Castleを入れて性能比較しました。
----
なんかいろいろ勘違いしているので助けてください(泣
7月28日(現地時間)にJava SE 7およびJDK7がリリースされました。
楕円曲線暗号(ECC)- いくつかのECCベースのアルゴリズム(ECDSA/ECDH)を提供する新しいネイティブ・プロバイダがJava SE 7リリースに追加されました。
Java SE 6にも
Java ™ Cryptography Architecture Standard Algorithm Name Documentation にあるように、"EC"および"HOGEwithECDSA"が使えるみたいなので、Java SE 7のネイティブプロバイダとの性能比較とかできるのでは?と思い、早速コードを書いてみました。
作成したソースコードはこちら:
EC.java [8/14更新]
import java.security.InvalidKeyException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Signature;
import java.security.SignatureException;
public class EC {
public static void main(String[] args) {
byte[] message = "The quick brown fox jumps over the lazy dog"
.getBytes();
byte[] sign = null;
KeyPairGenerator keyPairGenerator = null;
long generateKeyPairStart;
long generateKeyPairEnd;
try {
keyPairGenerator = KeyPairGenerator.getInstance("EC");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
return;
}
SecureRandom secureRandom = new SecureRandom();
keyPairGenerator.initialize(256, secureRandom);
generateKeyPairStart = System.nanoTime();
KeyPair keyPair = keyPairGenerator.generateKeyPair();
generateKeyPairEnd = System.nanoTime();
PrivateKey privateKey = keyPair.getPrivate();
PublicKey publicKey = keyPair.getPublic();
Signature signatureSign = null;
long signStart = 0;
long signEnd = 0;
try {
signatureSign = Signature.getInstance("NONEwithECDSA");
signatureSign.initSign(privateKey, secureRandom);
signatureSign.update(message);
signStart = System.nanoTime();
sign = signatureSign.sign();
signEnd = System.nanoTime();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
return;
} catch (InvalidKeyException e) {
e.printStackTrace();
return;
} catch (SignatureException e) {
e.printStackTrace();
return;
}
Signature signatureVerify = null;
boolean verifyResult;
long verifyStart;
long verifyEnd;
try {
signatureVerify = Signature.getInstance("NONEwithECDSA");
signatureVerify.initVerify(publicKey);
signatureVerify.update(message);
verifyStart = System.nanoTime();
verifyResult = signatureVerify.verify(sign);
verifyEnd = System.nanoTime();
if (verifyResult) {
System.out.print("OK");
System.out.print("\t");
} else {
System.out.print("NG");
System.out.print("\t");
}
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
return;
} catch (InvalidKeyException e) {
e.printStackTrace();
return;
} catch (SignatureException e) {
e.printStackTrace();
return;
}
System.out.print(generateKeyPairEnd - generateKeyPairStart);
System.out.print("\t");
System.out.print(signEnd - signStart);
System.out.print("\t");
System.out.print(verifyEnd - verifyStart);
System.out.println();
}
}
結果:
Java SE 6では(そのままの環境では)ECが使えないみたいです。コンパイルはできるのですが、NoSuchAlgorithmException が出てしまいました。
java.security.NoSuchAlgorithmException: EC KeyPairGenerator not available
at java.security.KeyPairGenerator.getInstance(KeyPairGenerator.java:176)
at EC.main(EC.java:21)
ということで、当初やりたかった性能比較はできませんでした。
とりあえず、Java SE 7で署名と検証ができているのでよしとするかな...。
----
[追記]記事を書いた後に調べたり、コメントをいただいた通り、Java SE 6では別途ECの実装が必要でした。
Bouncy CastleをJava SE 6に設定、コードの処理の始めと終わりに時間取得と差をとるコードを埋め込んで、性能比較しました。
※本当は時間取得関数の粒度の考慮やプロファイラを使った測定をするのですが、概ねの感覚をつかむためだけなので簡易的なものにしました。
表の値は1000回の平均値です。
| 鍵ペア生成(generateKeyPair) | 署名(sign) | 検証(verify) |
Java SE 6(Bouncy Castle)[ns] | 196824923 | 45081129 | 39902893 |
Java SE 7[ns] | 5446514 | 3902657 | 5771905 |
性能比[%](6/7) | 3614 | 1155 | 691.3 |
時間比[%](7/6) | 0.02767 | 0.08657 | 0.1447 |
おー、大幅に速くなりました。
別途実装を用意しなくてもよくなったので、Java SE 7を用いたECCを使うシステムに期待大です。
コメントを頂いた
@satorukannoさん、line君、ありがとうございました。
line 返信
http://download.oracle.com/javase/6/docs/technotes/guides/security/SunProviders.html#SunJSSEProvider
によると
Ciphersuites that use Elliptic Curve Cryptography (ECDSA, ECDH, ECDHE, ECDH_anon) require that a JCE crypto provider with the following properties be installed:
ということなので、Java6だとECの実装が別途必要で、Java7ではそれが標準で含まれるようになった…ということでは。
R SATO 返信
ありがとうございます。
この記事を書いた後、同じ情報にたどり着いていました。
Google+でも同様のアドバイスをいただいています。
https://plus.google.com/109414807675364038758/posts/4mVYRA8fo81
> Interfaceだけ規定されているだけだったはずなので,別途BoucyCastleなどのライブラリを使う必要があったような気がするぞぃ.
ということで、Java SE 6にはBouncyCastleを入れてまとめ直します。