Skip to content
nov edited this page Sep 9, 2015 · 8 revisions

JSON Web Signature (JWS)

Supported Signing Algorithms

These values are supported as signing algorithms.

  • HS256 (HMAC-SHA256)
  • HS384 (HMAC-SHA384)
  • HS512 (HMAC-SHA512)
  • RS256 (RSA-SHA256)
  • RS384 (RSA-SHA384)
  • RS512 (RSA-SHA512)
  • ES256 (ECDSA-SHA256)
  • ES384 (ECDSA-SHA384)
  • ES512 (ECDSA-SHA512)

These 3 are not supported.

  • PS256
  • PS384
  • PS512

For each algorithm details, read [RFC7518] JSON Web Algorithms (JWA).

If you don't sign your JWT, then none is used.

Key Representation

Supported key representations are

  • String (for shared key)
  • OpenSSL::PKey::RSA
  • OpenSSL::PKey::EC
  • JSON::JWK
  • JSON::JWK::Set
  • :skip_verification # NOTE: magic word for skipping signature verification

For HMAC keys, String, JSON::JWK and JSON::JWK::Set instances are available.

For RSA/ECDSA keys, OpenSSL::PKey::RSA, OpenSSL::PKey::EC, JSON::JWK and JSON::JWK::Set instances are available.

String-represented RSA/ECDSA keys are not supported.

JSON::JWK::Set key works only when your JWT header includes kid attributes.

About JSON::JWK and JSON::JWK::Set, please read JWK.

Signing

In this gem, you'll generate a JSON::JWT instance, then call JSON::JWT#sign(key, algorithm).

How to generate a JSON::JWT instance is described in JWT.

For historical reasons, HS256 is the default when signing, but I recommend you to use RS256 if possible.

Using shared key isn't a good choice for assertion signature in general.

HMAC-SHA***

shared_key = 'shared-key'
jwt.sign(shared_key) # HS256 is the default
jwt.sign(shared_key, :HS384)
jwt.sign(shared_key, :HS512)

RSA-SHA***

private_key = OpenSSL::PKey::RSA.new(2048)
jwt.sign(private_key, :RS256)
jwt.sign(private_key, :RS384)
jwt.sign(private_key, :RS512)

ECDSA-SHA

private_key = OpenSSL::PKey::EC.new('prime256v1').generate_key
jwt.sign(private_key, :ES256)

private_key = OpenSSL::PKey::EC.new('secp384r1').generate_key
jwt.sign(private_key, :ES384)

private_key = OpenSSL::PKey::EC.new('secp521r1').generate_key
jwt.sign(private_key, :ES512)

Verifying

JSON::JWT#decode(jwt_string, key) is for decoding and verifying compact-seiralized JWT string.

public_key = OpenSSL::PKey::RSA.new <<-PEM
-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEAx9vNhcvSrxjsegZAAo4OEuoZOV/oxINEeWneJYczS80/bQ1J6lSS
 :
-----END RSA PUBLIC KEY-----
PEM

jwt = JSON::JWT.decode 'eyJ...', public_key

You can also skip signature verification at decoding, then verify the signature later by calling JSON::JWS#verify!(key).

jwt = JSON::JWT.decode 'eyJ...', :skip_verification
# DO SOMETHING
jwt.verify! public_key
Clone this wiki locally