Skip to content

Instantly share code, notes, and snippets.

@jeffsheets
Last active March 24, 2021 02:00
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jeffsheets/b6cc38cf791be2d51c707aca927c9831 to your computer and use it in GitHub Desktop.
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
client:
publicKey: |
-----BEGIN PUBLIC KEY-----
yourBigLongPublicKeyShouldBeHere
-----END PUBLIC KEY-----
privateKey: |
-----BEGIN PRIVATE KEY-----
yourBigLongPrivateKeyShouldGoHere_ForTESTINGOnly_DontDoThisWithProductionKeys
-----END PRIVATE KEY-----
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-----
dependencies {
compile 'com.auth0:java-jwt:3.4.0'
compile 'org.bouncycastle:bcprov-jdk15on:1.60'
}
@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
@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
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