You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Json Web Token's is a way of Authenticating. A token is on the form of header.claims.signature where the header and claims are 64base encoded json objects and the signature 64base encoded bytearray. This token is attached in the html header as Authorization: token header.claims.signature.
I suggest using RSA as the signature and claims to be the user information. The claims may also include a scope of which the token can be used to authenticate. For instance a token might be issued only to allow access to ORE.
Expiration
The token also contains a claim that tells the client for instance ore that this token is valid until a certain date and time; this is often 5 or 15 min. The token then contains a refresh token within the claims that can be used to generate a new token. This refresh token is kept in a db on the auth server and can be invalidated to turn of access for this token.
Implementation
The auth server implementation should have an endpoint that allow tokens to be issued in an exchange of credentials. This token is then returned to the user and can be used to verify their identity.
Public Key endpoint should return the publickey of the Private Key that is used to sign the tokens. This will allow client implementation to retriever a public key that can be used to verify the JWT tokens is signed by the auth server.
Refresh endpoint to exchange a token that can be invalidated to a JWT token that can be used to authenticate.
Furthermorethe a client implementation should always check that the header is an exact match or just ignore it completely.
Ore
This will be used with the new ORE API V2 and the vue frontend for ORE.
Why? What advantages does this give? What's wrong with using an opaque token which is looked up in the database and has associated scopes?
JWTs are too easy to do wrong. I've seen too many applications supporting the NONE algorithm. The RSA is easy to fuck up with a padding oracle vulnerability if you're doing encryption. Too many library implementations don't check MACs properly.
Why do we want to send and have the claims persisted by the client?
The token also contains a claim that tells the client for instance ore that this token is valid until a certain date and time; this is often 5 or 15 min. The token then contains a refresh token within the claims that can be used to generate a new token. This refresh token is kept in a db on the auth server and can be invalidated to turn of access for this token.
In other words, you can no longer immediately invalidate tokens - because there's a window of validity where there's nothing you can do with the token because it's perfectly valid.
And we're still using a database for the refresh tokens!
Really, what is the advantage of all this complexity? You're still using a database for the refresh token storage. Why can't you expose a simple API to consuming services in order to check these tokens?
JWTs are too easy to do wrong. I've seen too many applications supporting the NONE algorithm. The RSA is easy to fuck up with a padding oracle vulnerability if you're doing encryption. Too many library implementations don't check MACs properly.
I have made a small snippet to answer the part about the None algorithm or more exact an equivalent implementation
python
ifauthenticate(token) ortrue:
Furthermore I dont know if you skipped this part or more likely I wrote it badly
Furthermorethe a client implementation should always check that the header is an exact match or just ignore it completely.
This translates to; we are only going to support one algorithm, in short we don't necessarily care about the header and the specified algorithm.
To answer the second part about RSA is to damn hard. I dont see my self or anyone implementing RSA it's too great of security risk. I would use the RSA/ECB/OAEPWithSHA-256AndMGF1Padding this is on the form algorithm/mode/padding. This algorithm exists both in java and pyCrypto
In other words, you can no longer immediately invalidate tokens - because there's a window of validity where there's nothing you can do with the token because it's perfectly valid.
And why is this a problem, you can invalidate the refresh token and yes it can take up to 5-15min depending on what we decide the lifetime of a token is. I do not see a problem nor does security obsessed Google.
Really, what is the advantage of all this complexity? You're still using a database for the refresh token storage. Why can't you expose a simple API to consuming services in order to check these tokens?
Well I'm glad you asked. Fist of all it will reduce the load on the authentication server by only needing to do a round trip every 5min or 15min to refresh the token. By using this system we would also make authentication stateless and services is no longer require to lookup the API token in a DB. This is most useful if you have services running on different servers and most notably regions.
JWT is not hard to do right and to be honest you should always create your own implementation that suits your needs. This implementation might just ignore any header and only check if the signature against one algorithm.
I have made a small snippet to answer the part about the None algorithm or more exact an equivalent implementation
If I'm following your point here correctly, you're using this to illustrate the lack of security regarding implementations which support this alg. I don't disagree, but this mistake has been made many many times!
Furthermorethe a client implementation should always check that the header is an exact match or just ignore it completely.
I wasn't sure what you meant by header. But you're right, applications should hardcode a particular algorithm and refuse to accept anything else. I still see people do this wrong regularly though.
I dont see my self or anyone implementing RSA it's too great of security risk.
Agreed, implementing your own crypto is never a good idea.
I would use the RSA/ECB/OAEPWithSHA-256AndMGF1Padding
Can you explain your reasoning behind this choice?
This algorithm exists both in java and pyCrypto
Library support is always good.
And why is this a problem, you can invalidate the refresh token and yes it can take up to 5-15min depending on what we decide the lifetime of a token is. I do not see a problem nor does security obsessed Google.
Regardless as to whether you see a problem or not, it's still a fact of using this sort of approach and should be acknowledged.
Well I'm glad you asked. Fist of all it will reduce the load on the authentication server by only needing to do a round trip every 5min or 15min to refresh the token.
And shift load onto the application servers which now need to verify signatures. Have you profiled the load generated by a database-lookup approach? Is this currently a bottlekneck?
By using this system we would also make authentication stateless and services is no longer require to lookup the API token in a DB.
I don't disagree (with the exception of the refresh logic).
This is most useful if you have services running on different servers and most notably regions.
Is the latency associated with auth checking large enough that this is unequivocally a bottlekneck? Have you got metrics for this? I keep asking this, because otherwise it sounds like premature optimisation.
to be honest you should always create your own implementation that suits your needs
Are you advocating rolling your own library for a security critical application?
Some more questions:
Why should claims be visible to the client? Is encryption the answer if claims shouldn't be visible?
I would like to start by saying that I think it's good to outline all possible issues, even if they non existence. For instance, how do we prevent man in the middle attack on the public key at the end point. This could be a problem, but since we would be using https, and all clients should only try to access the public key by https.
to be honest you should always create your own implementation that suits your needs: Are you advocating rolling your own library for a security critical application?
Yes and no, im not advocating you to write any sensitive security algorithms like RSA! But JWT is quite simple in it's nature. I'm arguing that you dont necessarily need to implement all features of JWT but only the features your application is going to need. If you have absolutely no idea how any of this works, you should absolutely not try.
Is the latency associated with auth checking large enough that this is unequivocally a bottlekneck? Have you got metrics for this? I keep asking this, because otherwise it sounds like premature optimisation.
Currently theres no evidence for any kind of bottleneck. This will not resolve any performance issues at the moment, but will make a short authentication server outage less potent.
Shift load onto the application servers which now need to verify signatures. Have you profiled the load generated by a database-lookup approach? Is this currently a bottlekneck?
Theres two big public private key cryptographic algorithms, DSA and RSA. DSA is quick for signature generation but slow for validation. Where as RSA is slow at signing but quick at validating the signature. You can run a benchmark with opensll speed rsa
sign
verify
sign/s
verify/s
rsa 512 bits
0.000830s
0.000047s
1205.3
21359.0
rsa 1024 bits
0.005028s
0.000217s
198.9
4602.9
rsa 2048 bits
0.035149s
0.001015s
28.5
984.8
rsa 4096 bits
0.242308s
0.003620s
4.1
276.3
The above result is from a MacBook Pro (Retina, 13-inch, Early 2015) 2,7 GHz Intel Core i5 and it takes a single ms to verify and bit longer to sign a 2048 bit key, I dont even see redis beating this.
I would use the RSA/ECB/OAEPWithSHA-256AndMGF1Padding. Can you explain your reasoning behind this choice?
Yes I can OAEP is not vulnerable to padding oracle attack, and sha-256 is just a preference over sha-1 it does not have any real security benefits.
Why should claims be visible to the client? Is encryption the answer if claims shouldn't be visible?
If we want to store data stateless for the user the best option is to save it on the client. If we want to hide some data an option could be to encrypt it. JWT does not necessarily replace all database lookups, but only the once related to validate the user and the users id. This user id can then be used to lookup service specific data.
Edit: Sensitive data should never be stored in the claims, even if encrypted. This is duo to the fact that any encryption might be broken.
Quick comment, OAEP is only secure for encrypting not signing, we should use PKCS#1 v1.5. That said, PKCS#1 v1.5 padding for signature generation has not been broken (unlike PKCS#1 v1.5 padding for encryption, which does have vulnerabilities)
Activity
lol768 commentedon Mar 6, 2018
Why? What advantages does this give? What's wrong with using an opaque token which is looked up in the database and has associated scopes?
JWTs are too easy to do wrong. I've seen too many applications supporting the NONE algorithm. The RSA is easy to fuck up with a padding oracle vulnerability if you're doing encryption. Too many library implementations don't check MACs properly.
Why do we want to send and have the claims persisted by the client?
In other words, you can no longer immediately invalidate tokens - because there's a window of validity where there's nothing you can do with the token because it's perfectly valid.
And we're still using a database for the refresh tokens!
Really, what is the advantage of all this complexity? You're still using a database for the refresh token storage. Why can't you expose a simple API to consuming services in order to check these tokens?
Defman commentedon Mar 7, 2018
I have made a small snippet to answer the part about the None algorithm or more exact an equivalent implementation
python
Furthermore I dont know if you skipped this part or more likely I wrote it badly
This translates to; we are only going to support one algorithm, in short we don't necessarily care about the header and the specified algorithm.
To answer the second part about RSA is to damn hard. I dont see my self or anyone implementing RSA it's too great of security risk. I would use the
RSA/ECB/OAEPWithSHA-256AndMGF1Paddingthis is on the formalgorithm/mode/padding. This algorithm exists both in java and pyCryptoAnd why is this a problem, you can invalidate the refresh token and yes it can take up to 5-15min depending on what we decide the lifetime of a token is. I do not see a problem nor does security obsessed Google.
Well I'm glad you asked. Fist of all it will reduce the load on the authentication server by only needing to do a round trip every 5min or 15min to refresh the token. By using this system we would also make authentication stateless and services is no longer require to lookup the API token in a DB. This is most useful if you have services running on different servers and most notably regions.
Theres a great post on Medium about pros and cons in using JWT
JWT is not hard to do right and to be honest you should always create your own implementation that suits your needs. This implementation might just ignore any header and only check if the signature against one algorithm.
lol768 commentedon Mar 7, 2018
If I'm following your point here correctly, you're using this to illustrate the lack of security regarding implementations which support this
alg. I don't disagree, but this mistake has been made many many times!I wasn't sure what you meant by header. But you're right, applications should hardcode a particular algorithm and refuse to accept anything else. I still see people do this wrong regularly though.
Agreed, implementing your own crypto is never a good idea.
Can you explain your reasoning behind this choice?
Library support is always good.
Regardless as to whether you see a problem or not, it's still a fact of using this sort of approach and should be acknowledged.
And shift load onto the application servers which now need to verify signatures. Have you profiled the load generated by a database-lookup approach? Is this currently a bottlekneck?
I don't disagree (with the exception of the refresh logic).
Is the latency associated with auth checking large enough that this is unequivocally a bottlekneck? Have you got metrics for this? I keep asking this, because otherwise it sounds like premature optimisation.
Are you advocating rolling your own library for a security critical application?
Some more questions:
Defman commentedon Mar 9, 2018
I would like to start by saying that I think it's good to outline all possible issues, even if they non existence. For instance, how do we prevent man in the middle attack on the public key at the end point. This could be a problem, but since we would be using https, and all clients should only try to access the public key by https.
Yes and no, im not advocating you to write any sensitive security algorithms like RSA! But JWT is quite simple in it's nature. I'm arguing that you dont necessarily need to implement all features of JWT but only the features your application is going to need. If you have absolutely no idea how any of this works, you should absolutely not try.
Currently theres no evidence for any kind of bottleneck. This will not resolve any performance issues at the moment, but will make a short authentication server outage less potent.
Theres two big public private key cryptographic algorithms, DSA and RSA. DSA is quick for signature generation but slow for validation. Where as RSA is slow at signing but quick at validating the signature. You can run a benchmark with
opensll speed rsaThe above result is from a
MacBook Pro (Retina, 13-inch, Early 2015) 2,7 GHz Intel Core i5and it takes a single ms to verify and bit longer to sign a 2048 bit key, I dont even see redis beating this.Yes I can OAEP is not vulnerable to padding oracle attack, and sha-256 is just a preference over sha-1 it does not have any real security benefits.
If we want to store data stateless for the user the best option is to save it on the client. If we want to hide some data an option could be to encrypt it. JWT does not necessarily replace all database lookups, but only the once related to validate the user and the users id. This user id can then be used to lookup service specific data.
Edit: Sensitive data should never be stored in the claims, even if encrypted. This is duo to the fact that any encryption might be broken.
Defman commentedon Mar 9, 2018
Quick comment, OAEP is only secure for encrypting not signing, we should use PKCS#1 v1.5. That said, PKCS#1 v1.5 padding for signature generation has not been broken (unlike PKCS#1 v1.5 padding for encryption, which does have vulnerabilities)
paragonie-scott commentedon May 16, 2018
Correction: You should be using PSS not PKCS#1 v1.5.
Furthermore, you may want to consider not doing RSA at all. If you must, only do so very carefully.