From 8db623bb9e77634a5a2cd019cd26960faaf10e52 Mon Sep 17 00:00:00 2001 From: constantine2nd Date: Sat, 17 Feb 2018 15:54:53 +0100 Subject: [PATCH 1/3] Added Nimbus library - JWT with RSA Encryption --- pom.xml | 5 +++ .../scala/code/api/util/CertificateUtil.scala | 45 ++++++++++++++++++- 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index cc2180df9..cb9c8afc3 100644 --- a/pom.xml +++ b/pom.xml @@ -334,6 +334,11 @@ java-jwt 3.3.0 + + com.nimbusds + nimbus-jose-jwt + 4.23 + diff --git a/src/main/scala/code/api/util/CertificateUtil.scala b/src/main/scala/code/api/util/CertificateUtil.scala index ffd778029..e255e1634 100644 --- a/src/main/scala/code/api/util/CertificateUtil.scala +++ b/src/main/scala/code/api/util/CertificateUtil.scala @@ -4,8 +4,11 @@ import java.io.FileInputStream import java.security.interfaces.{RSAPrivateKey, RSAPublicKey} import java.security.{PublicKey, _} import javax.crypto.Cipher - import code.api.util.CryptoSystem.CryptoSystem +import com.nimbusds.jose.crypto.RSAEncrypter +import com.nimbusds.jose.{EncryptionMethod, JWEAlgorithm, JWEHeader} +import com.nimbusds.jwt.EncryptedJWT +import code.util.Helper.MdcLoggable import net.liftweb.util.{Helpers, Props} @@ -14,7 +17,7 @@ object CryptoSystem extends Enumeration { val RSA = Value } -object CertificateUtil { +object CertificateUtil extends MdcLoggable { lazy val (publicKey: RSAPublicKey, privateKey: RSAPrivateKey) = APIUtil.getPropsAsBoolValue("jwt.use.ssl", false) match { case true => @@ -95,6 +98,44 @@ object CertificateUtil { cipher.doFinal(encrypted) } + def getClaimSet(payload: String) = { + import com.nimbusds.jose.util.Base64URL + import com.nimbusds.jwt.PlainJWT + // {"alg":"none"}// {"alg":"none"} + val header = "eyJhbGciOiJub25lIn0" + val plainJwt = new PlainJWT(new Base64URL(header), new Base64URL(payload)) + plainJwt.getJWTClaimsSet + } + def encryptJwtWithRsa(jwtPayload: String) = { + // Request JWT encrypted with RSA-OAEP-256 and 128-bit AES/GCM + val header = new JWEHeader(JWEAlgorithm.RSA_OAEP_256, EncryptionMethod.A128GCM) + // Create an encrypter with the specified public RSA key + val encrypter = new RSAEncrypter(publicKey) + // Create the encrypted JWT object + val encryptedJWT = new EncryptedJWT(header, CertificateUtil.getClaimSet(jwtPayload)) + // Do the actual encryption + encryptedJWT.encrypt(encrypter) + logger.debug("encryptedJWT.serialize(): " + encryptedJWT.serialize()) + // Return JWT + encryptedJWT.serialize() + } + def decryptJwtWithRsa(jwt: String) = { + import com.nimbusds.jose.crypto.RSADecrypter + import com.nimbusds.jwt.EncryptedJWT + // Parse back// Parse back + val jwtParsed = EncryptedJWT.parse(jwt) + System.out.println("decryptJwtWithRsa: " + jwtParsed.serialize()) + // Create a decrypter with the specified private RSA key + val decrypter = new RSADecrypter(privateKey) + jwtParsed.decrypt(decrypter) + logger.debug("jwt: " + jwt) + logger.debug("getState: " + jwtParsed.getState) + logger.debug("getJWTClaimsSet: " + jwtParsed.getJWTClaimsSet) + logger.debug("getCipherText: " + jwtParsed.getCipherText) + logger.debug("getAuthTag: " + jwtParsed.getAuthTag) + jwtParsed.serialize() + } + @throws[Exception] def main(args: Array[String]): Unit = { From 4349f574ae069f5cae48669a2d4377d266ceddd6 Mon Sep 17 00:00:00 2001 From: constantine2nd Date: Sat, 17 Feb 2018 16:26:19 +0100 Subject: [PATCH 2/3] Added Nimbus library - JWT with RSA Encryption --- src/main/scala/code/api/util/CertificateUtil.scala | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/main/scala/code/api/util/CertificateUtil.scala b/src/main/scala/code/api/util/CertificateUtil.scala index e255e1634..190ed51f8 100644 --- a/src/main/scala/code/api/util/CertificateUtil.scala +++ b/src/main/scala/code/api/util/CertificateUtil.scala @@ -4,9 +4,10 @@ import java.io.FileInputStream import java.security.interfaces.{RSAPrivateKey, RSAPublicKey} import java.security.{PublicKey, _} import javax.crypto.Cipher + import code.api.util.CryptoSystem.CryptoSystem import com.nimbusds.jose.crypto.RSAEncrypter -import com.nimbusds.jose.{EncryptionMethod, JWEAlgorithm, JWEHeader} +import com.nimbusds.jose.{EncryptionMethod, JOSEObject, JWEAlgorithm, JWEHeader} import com.nimbusds.jwt.EncryptedJWT import code.util.Helper.MdcLoggable import net.liftweb.util.{Helpers, Props} @@ -98,21 +99,22 @@ object CertificateUtil extends MdcLoggable { cipher.doFinal(encrypted) } - def getClaimSet(payload: String) = { + def getClaimSet(jwt: String) = { import com.nimbusds.jose.util.Base64URL import com.nimbusds.jwt.PlainJWT // {"alg":"none"}// {"alg":"none"} val header = "eyJhbGciOiJub25lIn0" - val plainJwt = new PlainJWT(new Base64URL(header), new Base64URL(payload)) + val parts: Array[Base64URL] = JOSEObject.split(jwt) + val plainJwt = new PlainJWT(new Base64URL(header), (parts(1))) plainJwt.getJWTClaimsSet } - def encryptJwtWithRsa(jwtPayload: String) = { + def encryptJwtWithRsa(jwt: String) = { // Request JWT encrypted with RSA-OAEP-256 and 128-bit AES/GCM val header = new JWEHeader(JWEAlgorithm.RSA_OAEP_256, EncryptionMethod.A128GCM) // Create an encrypter with the specified public RSA key val encrypter = new RSAEncrypter(publicKey) // Create the encrypted JWT object - val encryptedJWT = new EncryptedJWT(header, CertificateUtil.getClaimSet(jwtPayload)) + val encryptedJWT = new EncryptedJWT(header, CertificateUtil.getClaimSet(jwt)) // Do the actual encryption encryptedJWT.encrypt(encrypter) logger.debug("encryptedJWT.serialize(): " + encryptedJWT.serialize()) From d90bbd5357332329211382df5b47c5251cea00d1 Mon Sep 17 00:00:00 2001 From: constantine2nd Date: Sat, 17 Feb 2018 21:01:20 +0100 Subject: [PATCH 3/3] JWT with RSA Encryption added to response --- src/main/scala/code/api/GatewayLogin.scala | 7 ++++++- src/main/scala/code/api/util/CertificateUtil.scala | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/main/scala/code/api/GatewayLogin.scala b/src/main/scala/code/api/GatewayLogin.scala index 485ded743..2ccf74b21 100755 --- a/src/main/scala/code/api/GatewayLogin.scala +++ b/src/main/scala/code/api/GatewayLogin.scala @@ -107,7 +107,12 @@ object GatewayLogin extends RestHelper with MdcLoggable { //Invalid Signing configuration / Couldn't convert Claims. logger.error(exception) } - jwt + APIUtil.getPropsAsBoolValue("jwt.use.ssl", false) match { + case true => + CertificateUtil.encryptJwtWithRsa(jwt) + case false => + jwt + } } def parseJwt(parameters: Map[String, String]): Box[String] = { diff --git a/src/main/scala/code/api/util/CertificateUtil.scala b/src/main/scala/code/api/util/CertificateUtil.scala index 190ed51f8..723087edf 100644 --- a/src/main/scala/code/api/util/CertificateUtil.scala +++ b/src/main/scala/code/api/util/CertificateUtil.scala @@ -124,7 +124,7 @@ object CertificateUtil extends MdcLoggable { def decryptJwtWithRsa(jwt: String) = { import com.nimbusds.jose.crypto.RSADecrypter import com.nimbusds.jwt.EncryptedJWT - // Parse back// Parse back + // Parse back val jwtParsed = EncryptedJWT.parse(jwt) System.out.println("decryptJwtWithRsa: " + jwtParsed.serialize()) // Create a decrypter with the specified private RSA key