1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
|
# frozen_string_literal: true
module JSONWebToken
class RSAToken < Token
ALGORITHM = 'RS256'
attr_reader :key_file
def initialize(key_file)
super()
@key_file = key_file
end
def encoded
self.class.encode(payload, key, kid)
end
def self.encode(payload, key, kid)
headers = { kid: kid, typ: 'JWT' }
JWT.encode(payload, key, ALGORITHM, headers)
end
def self.decode(token, key)
JWT.decode(token, key, true, { algorithm: ALGORITHM })
end
private
def key_data
@key_data ||= File.read(key_file)
end
def key
@key ||= OpenSSL::PKey::RSA.new(key_data)
end
def public_key
key.public_key
end
def kid
# calculate sha256 from DER encoded ASN1
kid = Digest::SHA256.digest(public_key.to_der)
# we encode only 30 bytes with base32
kid = Base32.encode(kid[0..29])
# insert colon every 4 characters
kid.scan(/.{4}/).join(':')
end
end
end
|