crystal-community / jwt

JWT implementation in Crystal
MIT License
206 stars 24 forks source link

Exception: Invalid EVP_PKEY when trying to encode #23

Closed absolutejam closed 5 years ago

absolutejam commented 5 years ago

Hey there!

Thanks for creating this shard; we need more great shards like this.

I'm trying to generate a JWT for Google OAuth2 but I'm hitting the following unhandled exception:

Unhandled exception: Invalid EVP_PKEY: error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag (OpenSSL::PKey::PKeyError)
  from lib/openssl_ext/src/openssl_ext/pkey.cr:9:7 in 'initialize'
  from lib/openssl_ext/src/openssl_ext/pkey.cr:8:5 in 'new'
  from lib/openssl_ext/src/openssl_ext/pkey.cr:28:11 in 'new'
  from lib/openssl_ext/src/openssl_ext/pkey.cr:18:7 in 'new'
  from lib/openssl_ext/src/openssl_ext/pkey.cr:16:5 in 'new'
  from lib/jwt/src/jwt.cr:102:34 in 'sign'
  from lib/jwt/src/jwt.cr:88:17 in 'encoded_signature'
  from lib/jwt/src/jwt.cr:25:5 in 'encode'
  from src/google-jwt-test.cr:13:5 in 'run'
  from src/google-jwt-test.cr:31:1 in '__crystal_main'
  from /usr/local/Cellar/crystal/0.29.0/src/crystal/main.cr:97:5 in 'main_user_code'
  from /usr/local/Cellar/crystal/0.29.0/src/crystal/main.cr:86:7 in 'main'
  from /usr/local/Cellar/crystal/0.29.0/src/crystal/main.cr:106:3 in 'main'

Code:

require "http/client"
require "jwt"

module Google::Jwt::Test
  extend self

  GOOGLE_CLIENT_ID       = "foo.apps.googleusercontent.com"
  GOOGLE_CLIENT_SECRET   = "bar"
  GOOGLE_SCOPE           = "https://www.googleapis.com/auth/devstorage.read_only"

  def run
    token = JWT.encode(
      {"foo" => "bar"},
      GOOGLE_CLIENT_SECRET,
      JWT::Algorithm::RS256,
      iss: GOOGLE_CLIENT_ID,
      scope: GOOGLE_SCOPE,
      aud: "https://www.googleapis.com/oauth2/v4/token",
      exp: (Time.now + 1.hour).to_unix,
      iat: Time.now.to_unix,
    )
  end
end

Google::Jwt::Test.run

System:

Crystal 0.29.0 (2019-06-06)

LLVM: 6.0.1
Default target: x86_64-apple-macosx

I'll try on my linux machine later. Could this be due to the OpenSSL version of the OS? (LibreSSL 2.6.5 in this case). EDIT: Same thing on Manjaro.

Any ideas?

Regards, James.

stakach commented 5 years ago

Hi @absolutejam I added the RS token support so we could talk to google. Here is the code we're using in production - at some point I'll get around to building a google shard

https://gist.github.com/stakach/5b4b658628773dcbce0a8cc4181bd5e0

This works for us on OSX, Ubuntu and RedHat - not sure if they are using Libre or Open. The format of the private key should be like:


pkey = "-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBgkqhki...\n-----END PRIVATE KEY-----\n"

Usage for the gist code above looks like:


signing_key = "-----BEGIN PRIVATE KEY-----..."
issuer = "user@service.iam.gserviceaccount.com"
scopes = "https://www.googleapis.com/auth/calendar"

auth = GoogleAuth.new(issuer, signing_key, scopes)
gcal = GoogleCalendar.new auth

gcal.sub = "user@domain.com"
gcal.events("user@domain.com", period_end: Time.local.at_end_of_day)

# returns todays event list for that user

Let me know how you travel. My guess would be the PKey is in the wrong format or the wrong param is being passed?

absolutejam commented 5 years ago

Oh! I was using the OAuth client secret as the second parameter instead of the private key from the .json!

Thanks for your help :smile:!

stakach commented 4 years ago

@absolutejam our google library is up https://github.com/PlaceOS/google