Last active
March 24, 2021 02:00
-
-
Save jeffsheets/b6cc38cf791be2d51c707aca927c9831 to your computer and use it in GitHub Desktop.
JWT creation in Spring Boot Groovy or Java with RSA 512 or 256 algorithm including steps to generate the keys stored as strings in yml properties file
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
client: | |
publicKey: | | |
-----BEGIN PUBLIC KEY----- | |
yourBigLongPublicKeyShouldBeHere | |
-----END PUBLIC KEY----- | |
privateKey: | | |
-----BEGIN PRIVATE KEY----- | |
yourBigLongPrivateKeyShouldGoHere_ForTESTINGOnly_DontDoThisWithProductionKeys | |
-----END PRIVATE KEY----- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
client: | |
publicKey: | | |
-----BEGIN PUBLIC KEY----- | |
yourBigLongPublicKeyShouldBeHere_DifferentForProd | |
-----END PUBLIC KEY----- | |
# privateKey from env variable for production | |
privateKey: | | |
-----BEGIN PRIVATE KEY----- | |
${CLIENT_PRIVATE_KEY} | |
-----END PRIVATE KEY----- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
dependencies { | |
compile 'com.auth0:java-jwt:3.4.0' | |
compile 'org.bouncycastle:bcprov-jdk15on:1.60' | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Service | |
class ClientJWTService { | |
@Value('${client.publicKey}') | |
String publicKeyString | |
@Value('${client.privateKey}') | |
String privateKeyString | |
Algorithm buildJwtAlgorithm() { | |
KeyFactory kf = KeyFactory.getInstance('RSA') | |
byte[] publicKeyBytes = new PemReader(new StringReader(publicKeyString)).readPemObject().getContent() | |
RSAPublicKey publicKey = (RSAPublicKey) kf.generatePublic(new X509EncodedKeySpec(publicKeyBytes)) | |
byte[] privateKeyBytes = new PemReader(new StringReader(privateKeyString)).readPemObject().getContent() | |
RSAPrivateKey privateKey = (RSAPrivateKey) kf.generatePrivate(new PKCS8EncodedKeySpec(privateKeyBytes)) | |
Algorithm.RSA512(publicKey, privateKey) | |
} | |
String generateJsonWebToken() { | |
Algorithm jwtSigningAlgorithm = buildJwtAlgorithm() | |
JWT.create() | |
.withIssuer('My Company') | |
.withAudience('urn::https://mycomp.any/v1.0/') | |
.withClaim('nameid', 'My Company') | |
.sign(jwtSigningAlgorithm) | |
} | |
} | |
//imports at bottom to make Gist look cleaner | |
import com.auth0.jwt.JWT | |
import com.auth0.jwt.algorithms.Algorithm | |
import org.bouncycastle.util.io.pem.PemReader | |
import org.springframework.beans.factory.annotation.Value | |
import org.springframework.stereotype.Service | |
import java.security.KeyFactory | |
import java.security.interfaces.RSAPrivateKey | |
import java.security.interfaces.RSAPublicKey | |
import java.security.spec.PKCS8EncodedKeySpec | |
import java.security.spec.X509EncodedKeySpec |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE) | |
class ClientJWTServiceSpec extends Specification { | |
@Autowired | |
ClientJWTService clientJWTService | |
void 'should generate JWT that is verifiable via the public key'() { | |
when: | |
String jwt = clientJWTService.generateJsonWebToken() | |
DecodedJWT decoded = JWT.decode(jwt) | |
then: | |
clientJWTService.buildJwtAlgorithm().verify(decoded) | |
} | |
void 'should generate JWT with correct contents'() { | |
when: | |
String jwt = clientJWTService.generateJsonWebToken() | |
DecodedJWT decoded = JWT.decode(jwt) | |
then: | |
decoded.getIssuer() == 'My Company' | |
decoded.getAudience()[0] == 'urn::https://mycomp.any/v1.0/' | |
decoded.getClaim('nameid').asString() == 'My Company' | |
new String(decoded.header.decodeBase64()) == '{"typ":"JWT","alg":"RS512"}' | |
new String(decoded.payload.decodeBase64()) == '{"aud":"urn::https://mycomp.any/v1.0/","iss":"My Company","nameid":"My Company"}' | |
} | |
} | |
import com.auth0.jwt.JWT | |
import com.auth0.jwt.interfaces.DecodedJWT | |
import org.springframework.beans.factory.annotation.Autowired | |
import org.springframework.boot.test.context.SpringBootTest | |
import spock.lang.Specification |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
ssh-keygen -t rsa -b 4096 -f jwt512_private.key | |
# Don't add passphrase | |
openssl rsa -in jwt512_private.key -pubout -outform PEM -out jwt512_public.key.pub | |
# convert private key to pkcs8 format in order to import it from Java | |
openssl pkcs8 -topk8 -in jwt512_private.key -inform pem -out jwt512_private_pkcs8.key -outform pem -nocrypt | |
#Credits to the following for the ideas for this script | |
# https://gist.github.com/ygotthilf/baa58da5c3dd1f69fae9 | |
# https://gist.github.com/destan/b708d11bd4f403506d6d5bb5fe6a82c5 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment