Java: 署名アルゴリズム
概要
Java では Signatureクラスを使用して任意のメッセージ (バイナリデータ) に対して電子署名を作成することができる。
以下は ECDSA 秘密鍵を使用して "hello, world" のバイナリ表現に署名し、公開鍵で検証する例である。
import java.security._
val generator = KeyPairGenerator.getInstance("EC")
val keyPair = generator.generateKeyPair()
val signer = Signature.getInstance("SHA512withECDSA")
val binary = "hello, world".getBytes("UTF-8")
signer.initSign(keyPair.getPrivate)
signer.update(binary)
val signature = signer.sign()
signature.map(x => f"$x%02X").mkString // => 304502204F9264F8C184BD3129C2566650A1A8F1...
signer.initVerify(keyPair.getPublic)
signer.update(binary)
signer.verify(signature) // => true
アルゴリズムに使用できる名前は以下の通り (大文字と小文字は区別しない)。
アルゴリズム | 対象データ [B] | 算出時間 [msec] | 検証時間 [msec] | 署名サイズ [B] |
---|---|---|---|---|
RSASSA-PSS |
1M | 10.77 | 4.62 | 256 |
NONEwithDSA |
20 | 1.98 | 1.91 | 63 |
SHA1withDSA |
1M | 5.26 | 5.28 | 47 |
SHA224withDSA |
1M | 5.70 | 6.93 | 64 |
SHA256withDSA |
1M | 5.43 | 7.02 | 63 |
NONEwithDSAinP1363FORMAT |
20 | 1.73 | 1.61 | 56 |
SHA1withDSAinP1363FORMAT |
1M | 5.11 | 5.18 | 40 |
SHA224withDSAinP1363FORMAT |
1M | 5.68 | 8.13 | 56 |
SHA256withDSAinP1363FORMAT |
1M | 5.73 | 8.77 | 56 |
NONEwithECDSA |
64 | 1.83 | 2.81 | 71 |
SHA1withECDSA |
1M | 6.54 | 8.97 | 70 |
SHA224withECDSA |
1M | 6.83 | 7.59 | 71 |
SHA256withECDSA |
1M | 6.49 | 8.09 | 71 |
SHA384withECDSA |
1M | 5.21 | 6.37 | 71 |
SHA512withECDSA |
1M | 5.36 | 5.48 | 72 |
NONEwithECDSAinP1363FORMAT |
64 | 1.60 | 3.02 | 64 |
SHA1withECDSAinP1363FORMAT |
1M | 7.74 | 8.56 | 64 |
SHA224withECDSAinP1363FORMAT |
1M | 5.63 | 6.71 | 64 |
SHA256withECDSAinP1363FORMAT |
1M | 6.66 | 7.06 | 64 |
SHA384withECDSAinP1363FORMAT |
1M | 5.78 | 6.09 | 64 |
SHA512withECDSAinP1363FORMAT |
1M | 4.30 | 5.72 | 64 |
MD2withRSA |
1M | 150.78 | 133.45 | 256 |
MD5withRSA |
1M | 11.09 | 3.55 | 256 |
MD5andSHA1withRSA |
1M | 13.18 | 8.56 | 256 |
NONEwithRSA |
20 | 4.70 | 0.11 | 256 |
SHA1withRSA |
1M | 10.40 | 6.44 | 256 |
SHA224withRSA |
1M | 8.91 | 5.24 | 256 |
SHA256withRSA |
1M | 9.88 | 3.93 | 256 |
SHA384withRSA |
1M | 7.78 | 3.34 | 256 |
SHA512withRSA |
1M | 8.67 | 4.86 | 256 |
SHA512/224withRSA |
1M | 8.05 | 3.18 | 256 |
SHA512/256withRSA |
1M | 8.08 | 3.37 | 256 |
NONEwith
から始まるアルゴリズムは署名対象のデータの大きさが固定されていたり上限の制約を持っている。これらは十分に小さい固定長のデータか、すでに別のアルゴリズムでハッシュ化された値に対して署名をするために用意されている。
SHA1withDSA
はデフォルトの KeyPairGenerator.getInstance("DSA")
が生成した鍵のサイズでは十分に安全ではないことから例外が発生するようになっている: java.security.InvalidKeyException: The security strength of SHA-1 digest algorithm is not sufficient for this key size
。このため、このアルゴリズムを使用する場合は KeyPairGenerator.initialize()
でサイズを指定する必要がある。
java version "13.0.2" OpenJDK Runtime Environment (build 13.0.2+8) OpenJDK 64-Bit Server VM (build 13.0.2+8, mixed mode, sharing)