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


とあるバッチ処理で繰り返し大量の署名付き 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.)との関係もよく分かりません。