Skip to content

Add EncodingKey & DecodingKey#113

Merged
Keats merged 4 commits intonextfrom
keys_struct
Jan 17, 2020
Merged

Add EncodingKey & DecodingKey#113
Keats merged 4 commits intonextfrom
keys_struct

Conversation

@Keats
Copy link
Copy Markdown
Owner

@Keats Keats commented Dec 29, 2019

No description provided.

@Keats Keats changed the title Add EncodingKey Add EncodingKey & DecodingKey Dec 29, 2019
@Keats Keats mentioned this pull request Dec 29, 2019
@Dowwie
Copy link
Copy Markdown
Contributor

Dowwie commented Jan 2, 2020

@Keats
Is there a pressing reason to use borrows? the lifetime requirements for EncodingKey and DecodingKey cascade all over my code base. Eliminating the borrows would be much more friendly.

@Keats
Copy link
Copy Markdown
Owner Author

Keats commented Jan 2, 2020

For EncodingKey not really, we could remove the lifetime. For DecodingKey we do not want to clone the secret/keys everytime we verify a token so they are needed.

@Dowwie
Copy link
Copy Markdown
Contributor

Dowwie commented Jan 2, 2020

DecodingKey is the bigger problem for me. To avoid "lifetime baggage", I'll probably end up creating DecodingKey on every request (passing it a pem String), and that's not putting me in a much better place than cloning on every decode.

@Keats
Copy link
Copy Markdown
Owner Author

Keats commented Jan 2, 2020

Why not instantiate it in a lazy_static or similar? The whole point of that API is to allow re-using the Encoding/Decoding keys to make it more performant.

@Dowwie
Copy link
Copy Markdown
Contributor

Dowwie commented Jan 2, 2020

@Keats
I'm willing to compromise with a lazy_static but haven't figured out an impl to satisfy the compiler without making some slight changes to DecodingKey::from_rsa_pem, changing the key param to String. Without changing this to String, I couldn't get lazy_static to work (temporary value exceptions). As you can see, I am using environment variable and cannot include_bytes because it requires use of a literal.

  /// If you are loading a public RSA key in a PEM format, use this.                                                                                    
    pub fn from_rsa_pem(key: String) -> Result<Self> {                                                                                                    
        let pem_key = PemEncodedKey::new(key.as_bytes())?;                                                                                                
          let content = pem_key.as_rsa_key()?;                                                                                                              
         Ok(DecodingKey { kind: DecodingKeyKind::SecretOrDer(Cow::Owned(content.to_vec())) })                                                              
     }   

an example of the lazy_static:

lazy_static! {
    static ref JWT_DECODING_KEY: DecodingKey<'static> = 
       DecodingKey::from_rsa_pem(
          fs::read_to_string(
            env::var("JWT_PUBKEY")
            .unwrap_or_else(|_| panic!("Failed to load JWT public key envvar"))
          ).unwrap()
       ).unwrap_or_else(|_| panic!("Failed to create JWT DecodingKey"));
}

and preferably make the same key param change to String for EncodingKey::from_rsa_pem

@Dowwie
Copy link
Copy Markdown
Contributor

Dowwie commented Jan 2, 2020

What do you think about modifying the from_rsa_pem functions accordingly?

@Keats
Copy link
Copy Markdown
Owner Author

Keats commented Jan 2, 2020

I would prefer keeping &[u8] for maximal flexibility.
In your lazy_static example, I think you need to define another variable for the env var:

lazy_static! {
    static ref SOME_STRING: String = env::var("JWT_PUBKEY").unwrap();
    // And there you can have your DecodingKey with &[u8] I think
    static ref OTHER: &'static [u8] = SOME_STRING.as_bytes();
}

@Dowwie
Copy link
Copy Markdown
Contributor

Dowwie commented Jan 2, 2020

@Keats I think I'm creating PEM files in an unsupported format. what command are you using to generate your PEM files? I was using this but the format is failing:
openssl req -x509 -days 365 -nodes -newkey rsa:2048 -keyout privkey.pem -out cert.pem

@Keats
Copy link
Copy Markdown
Owner Author

Keats commented Jan 2, 2020

x509 is not supported

Something like:

openssl genrsa -out private.pem 2048
openssl rsa -in private.pem -outform PEM -pubout -out public.pem

@Dowwie
Copy link
Copy Markdown
Contributor

Dowwie commented Jan 3, 2020

@Keats this PR seems sufficient for my needs.. no further issues/concerns to report

@Dowwie
Copy link
Copy Markdown
Contributor

Dowwie commented Jan 13, 2020

@Keats essentially, what are we achieving with these changes?

@Keats
Copy link
Copy Markdown
Owner Author

Keats commented Jan 13, 2020

You ensure the key is of the same type as the algorithm so you can't misuse it. Eg you want to decode a RSA token but put a HMAC key instead and it will fail immediately. It's not prevented at compile time sadly but that's better than nothing. I don't think we can have type safety at compile time without have one encode/decode function per algorithm family

@Keats Keats merged commit e46f8f9 into next Jan 17, 2020
@Keats Keats deleted the keys_struct branch January 17, 2020 19:18
JadedBlueEyes referenced this pull request in JadedBlueEyes/jsonwebtoken Apr 13, 2023
Add EncodingKey & DecodingKey
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants