Edited at

メモ: ruby-jwt の署名アルゴリズム別ベンチマーク

More than 1 year has passed since last update.

とあるバッチ処理で繰り返し大量の署名付き JWT を生成する事になり、今まで(深く)気にしてこなかったアルゴリズム別の性能差を確認してみた時のメモ。

※ HMAC の鍵長や ECDSA の使い方(曲線の選び方?)についてよく分かっていないので、条件がおかしいかもしれない。

require 'benchmark'

require 'jwt'
require 'digest/md5'

keys = {
HMAC: {
HS256: Digest::MD5.hexdigest('HS256'),
HS384: Digest::MD5.hexdigest('HS384'),
HS512: Digest::MD5.hexdigest('HS512'),
},
RSA: {
RS256: OpenSSL::PKey::RSA.generate(2048),
RS384: OpenSSL::PKey::RSA.generate(2048),
RS512: OpenSSL::PKey::RSA.generate(2048),
},
ECDSA: {
ES256: OpenSSL::PKey::EC.new('prime256v1').tap(&:generate_key),
ES384: OpenSSL::PKey::EC.new('secp384r1').tap(&:generate_key),
ES512: OpenSSL::PKey::EC.new('secp521r1').tap(&:generate_key),
},
}

n = 10_000

Benchmark.bm(15) do |bm|
keys.each do |group, algs|
algs.each do |alg, key|
bm.report("#{group} / #{alg}") do
n.times { JWT.encode({}, key, alg.to_s) }
end
end
end
end

__END__
user system total real
HMAC / HS256 0.280000 0.000000 0.280000 ( 0.289864)
HMAC / HS384 0.250000 0.000000 0.250000 ( 0.254620)
HMAC / HS512 0.260000 0.000000 0.260000 ( 0.255493)
RSA / RS256 6.140000 0.000000 6.140000 ( 6.146817)
RSA / RS384 6.140000 0.010000 6.150000 ( 6.155130)
RSA / RS512 6.140000 0.000000 6.140000 ( 6.151847)
ECDSA / ES256 0.810000 0.000000 0.810000 ( 0.815459)
ECDSA / ES384 7.140000 0.010000 7.150000 ( 7.149290)
ECDSA / ES512 3.610000 0.010000 3.620000 ( 3.627512)


備考: 実行環境など


追記: RbNaCl

cryptosphere/rbnacl がロード可能であれば HMAC 系アルゴリズムで RbNaCl を使うという事が書かれていたので試してみたところ、若干遅くなる模様。

                      user     system      total        real

HMAC / HS256 0.350000 0.000000 0.350000 ( 0.358537)
HMAC / HS384 0.260000 0.000000 0.260000 ( 0.264705)
HMAC / HS512 0.330000 0.000000 0.330000 ( 0.329434)
HMAC / HS512256 0.330000 0.000000 0.330000 ( 0.331153)

NaCl (Networking and Cryptography library) についてはよく分かっていません(jedisct1/libsodium も)。NaCl (ネットワーク応用通信研究所; Network Applied Communication Laboratory Ltd.)との関係もよく分かりません。