Skip to content

Instantly share code, notes, and snippets.

@andrhamm
Created May 10, 2018 15:55
Show Gist options
  • Select an option

  • Save andrhamm/ec2ad3feda5d7d0b0acecc02b93f4e15 to your computer and use it in GitHub Desktop.

Select an option

Save andrhamm/ec2ad3feda5d7d0b0acecc02b93f4e15 to your computer and use it in GitHub Desktop.

Revisions

  1. andrhamm created this gist May 10, 2018.
    38 changes: 38 additions & 0 deletions signing.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,38 @@
    # JWT-like tokens in Rails


    require 'openssl'
    require 'base64'

    # Generate encrypted signing key

    key = OpenSSL::PKey::RSA.new(2048)
    cipher = OpenSSL::Cipher.new('AES-128-CBC')
    # Note: rotating secret_key_base or signing_key_pem will
    # invalidate all previously generated tokens
    pem = key.to_pem cipher, Rails.application.secrets.secret_key_base
    encoded_pem = Base64.strict_encode64 pem
    // save encoded_pem to secrets.yml as `signing_key_pem`

    # Load key for signing/verifying encrypting/decrypting

    encoded_pem = Rails.application.secrets.signing_key_pem
    pem = Base64.strict_decode64 encoded_pem
    key = OpenSSL::PKey::RSA.new(pem, Rails.application.secrets.secret_key_base)

    # Sign some data, generate a token

    data = {"foo":"bar"}.to_json
    signature = key.sign(OpenSSL::Digest::SHA256.new, data)
    // package the data with the sig
    token = [Base64.strict_encode64(data), Base64.strict_encode64(signature)].join('.')

    # Verify a token

    data, signature = token.split('.').map {|encoded| Base64.strict_decode64 encoded};

    if key.public_key.verify(OpenSSL::Digest::SHA256.new, signature, data)
    puts 'the signature is valid'
    else
    puts 'the signature is invalid'
    end