JWT Auth requiring private key

169 views
Skip to first unread message

Tim Ross

unread,
Oct 1, 2018, 5:56:50 PM10/1/18
to vert.x
I am using the JWT Auth library to authenticate JWT grant access tokens.  I started with the client and server sharing a secret and created a jceks keystore with an HS256 shared key.  And that works fine.

We are now moving to private/public keys and the ES256 signature algorithm, so i generated a certificate for the public key and added it  as the ES256 alias to a jceks keystore.  JWT Auth fails authenticating the grant access tokens reporting:

Oct 01, 2018 17:10:20:558 io.vertx.ext.jwt.JWT
INFO: ES256 not available 

It seems the JWT class requires the private key to consider the algorithm available.

In this use case, the client has the private key and the authenticating server only has the public key.  To get around this,  I generated a fake private/public key pair and added its private key to the jceks store along with the cert chain from the  public key, all with the es256 alias.  That fixed the problem.  Even though the private key is not really paired with the public cert,  the private key is not needed for the JWT authentication.

Is the JWT class requiring the private key when using keystore intentional?  I really like using the keystores and would like to stay with them.

Btw, the JWT constructor does an e.printStackTrace() when catching the RuntimeException.  That hid  the error from the logs.

Thanks,
Tim








Paulo Lopes

unread,
Oct 2, 2018, 2:19:25 PM10/2/18
to vert.x
Hi Tim,

For 3.6 I've worked on clarifying the docs on how to works with keys. Since the release is not out yet I recommend you to read the current dev docs here:


Most of the things should work with 3.5. So in a nutshell I recommend you to avoid keystores (as there's to many assumptions and room for mistakes) and use openssl and pem files.

The docs will tell you how to generate the files. So there are 3 kinds of tokens:

* HS (HMac)
* RS (RSA)
* EC (Elliptic Curve)

It is important to know that EC algorithms might not be available with OpenJDK (they are on OracleJDK) or you might need to install the unlimited strength JCE extension:


So to the details:

JWT can issue tokens if there is a private key, and can validate tokens if there's either a public key it can verify tokens. If one of those is missing then the corresponding functionality is disabled:

For example for a RSA config all inline you would do:

JWTAuth provider = JWTAuth.create(vertx, new JWTAuthOptions()
     
.addPubSecKey(new PubSecKeyOptions()
       
.setAlgorithm("RS256")
       
.setPublicKey(
         
"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxPSbCQY5mBKFDIn1kggv\n" +
           
"Wb4ChjrctqD4nFnJOJk4mpuZ/u3h2ZgeKJJkJv8+5oFO6vsEwF7/TqKXp0XDp6IH\n" +
           
"byaOSWdkl535rCYR5AxDSjwnuSXsSp54pvB+fEEFDPFF81GHixepIbqXCB+BnCTg\n" +
           
"N65BqwNn/1Vgqv6+H3nweNlbTv8e/scEgbg6ZYcsnBBB9kYLp69FSwNWpvPmd60e\n" +
           
"3DWyIo3WCUmKlQgjHL4PHLKYwwKgOHG/aNl4hN4/wqTixCAHe6KdLnehLn71x+Z0\n" +
           
"SyXbWooftefpJP1wMbwlCpH3ikBzVIfHKLWT9QIOVoRgchPU3WAsZv/ePgl5i8Co\n" +
           
"qwIDAQAB")
       
.setSecretKey(
         
"MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDE9JsJBjmYEoUM\n" +
           
"ifWSCC9ZvgKGOty2oPicWck4mTiam5n+7eHZmB4okmQm/z7mgU7q+wTAXv9Oopen\n" +
           
"RcOnogdvJo5JZ2SXnfmsJhHkDENKPCe5JexKnnim8H58QQUM8UXzUYeLF6khupcI\n" +
           
"H4GcJOA3rkGrA2f/VWCq/r4fefB42VtO/x7+xwSBuDplhyycEEH2Rgunr0VLA1am\n" +
           
"8+Z3rR7cNbIijdYJSYqVCCMcvg8cspjDAqA4cb9o2XiE3j/CpOLEIAd7op0ud6Eu\n" +
           
"fvXH5nRLJdtaih+15+kk/XAxvCUKkfeKQHNUh8cotZP1Ag5WhGByE9TdYCxm/94+\n" +
           
"CXmLwKirAgMBAAECggEAeQ+M+BgOcK35gAKQoklLqZLEhHNL1SnOhnQd3h84DrhU\n" +
           
"CMF5UEFTUEbjLqE3rYGP25mdiw0ZSuFf7B5SrAhJH4YIcZAO4a7ll23zE0SCW+/r\n" +
           
"zr9DpX4Q1TP/2yowC4uGHpBfixxpBmVljkWnai20cCU5Ef/O/cAh4hkhDcHrEKwb\n" +
           
"m9nymKQt06YnvpCMKoHDdqzfB3eByoAKuGxo/sbi5LDpWalCabcg7w+WKIEU1PHb\n" +
           
"Qi+RiDf3TzbQ6TYhAEH2rKM9JHbp02TO/r3QOoqHMITW6FKYvfiVFN+voS5zzAO3\n" +
           
"c5X4I+ICNzm+mnt8wElV1B6nO2hFg2PE9uVnlgB2GQKBgQD8xkjNhERaT7f78gBl\n" +
           
"ch15DRDH0m1rz84PKRznoPrSEY/HlWddlGkn0sTnbVYKXVTvNytKSmznRZ7fSTJB\n" +
           
"2IhQV7+I0jeb7pyLllF5PdSQqKTk6oCeL8h8eDPN7awZ731zff1AGgJ3DJXlRTh/\n" +
           
"O6zj9nI8llvGzP30274I2/+cdwKBgQDHd/twbiHZZTDexYewP0ufQDtZP1Nk54fj\n" +
           
"EpkEuoTdEPymRoq7xo+Lqj5ewhAtVKQuz6aH4BeEtSCHhxy8OFLDBdoGCEd/WBpD\n" +
           
"f+82sfmGk+FxLyYkLxHCxsZdOb93zkUXPCoCrvNRaUFO1qq5Dk8eftGCdC3iETHE\n" +
           
"6h5avxHGbQKBgQCLHQVMNhL4MQ9slU8qhZc627n0fxbBUuhw54uE3s+rdQbQLKVq\n" +
           
"lxcYV6MOStojciIgVRh6FmPBFEvPTxVdr7G1pdU/k5IPO07kc6H7O9AUnPvDEFwg\n" +
           
"suN/vRelqbwhufAs85XBBY99vWtxdpsVSt5nx2YvegCgdIj/jUAU2B7hGQKBgEgV\n" +
           
"sCRdaJYr35FiSTsEZMvUZp5GKFka4xzIp8vxq/pIHUXp0FEz3MRYbdnIwBfhssPH\n" +
           
"/yKzdUxcOLlBtry+jgo0nyn26/+1Uyh5n3VgtBBSePJyW5JQAFcnhqBCMlOVk5pl\n" +
           
"/7igiQYux486PNBLv4QByK0gV0SPejDzeqzIyB+xAoGAe5if7DAAKhH0r2M8vTkm\n" +
           
"JvbCFjwuvhjuI+A8AuS8zw634BHne2a1Fkvc8c3d9VDbqsHCtv2tVkxkKXPjVvtB\n" +
           
"DtzuwUbp6ebF+jOfPK0LDuJoTdTdiNjIcXJ7iTTI3cXUnUNWWphYnFogzPFq9CyL\n" +
           
"0fPinYmDJpkwMYHqQaLGQyg=")
));


Tim Ross

unread,
Oct 3, 2018, 9:39:27 AM10/3/18
to vert.x
Thanks Paulo for the reply.

I already have the jceks keystores working for both HS256 jwt validation and ES256 jwt signing and validation.  The only trouble i ran into was when i wanted to use ES256 for jwt validation-only and i didn't have access to the private key. If I have these keystores working, would you still recommend moving to pem files?  I am currently generating them via an admin gui using bouncy castles java library. It is working out very nicely.

I do like using the keystore to encrypt the private key, although completely protecting the keystores password on a server is impossible .  Is encrypting the private keys pem file supported? I am also finding having a keystore that supports multiple algorithms rather convenient. 

Thanks again,
Tim

Paulo Lopes

unread,
Oct 3, 2018, 1:39:52 PM10/3/18
to vert.x
Hi Tim,

You should prefer pem files to keystores for several reasons:

1. keystores was a "bad" idea I had many many years ago with yoke and the heuristics i use to load keys are full of flaws
2. pem files seem to be what "everyone" standardized (google, facebook, etc... etc...)
3. with 3.6 I've introduced JWK to the jwt component so it can load standard keys (which are json representations that also contains keys in... pem format...)


So this means that either go with the new standard JWK or use the most popular format "pem". But indeed, both "pem" and JWK do not encrypt private keys which means that you're not as safe as you'd like. I think one way to mitigate this would be to have a mount that would be available at start of your application to load the keys and unmounted as soon as the application starts this reduced the window of making keys visible in your server... but indeed there's no real obvious "secure" way to store keys...

Tim Ross

unread,
Oct 3, 2018, 4:58:38 PM10/3/18
to vert.x
Ok thanks,  I'll follow your suggestion.

Tim
Reply all
Reply to author
Forward
0 new messages