Technical backend implementation
JWT Library
An example in SCALA
import java.security.interfaces.RSAPublicKey
import java.security.spec.{PKCS8EncodedKeySpec, X509EncodedKeySpec}
import java.security.{KeyFactory, KeyPairGenerator, PrivateKey, PublicKey}
import java.util.Date
import com.nimbusds.jose._
import com.nimbusds.jose.crypto._
import com.nimbusds.jwt.{JWTClaimsSet, SignedJWT}
object JWEBuilder {
def main(args: Array[String]): Unit = {
val (clientPubKey, clientPrivateKey) = getClientKeys()
val (iadvizePubKey, iadvizePrivateKey) = getIAdvizeKeys()
val JWS1 = createJWS(clientPrivateKey)
val JWE1 = createJWE(iadvizePubKey, JWS1)
println(s"JWS : ${JWS1.serialize()}")
println(s"JWE : ${JWE1.serialize()}")
val token = JWE1.serialize()
val JWS2 = decryptJWE(iadvizePrivateKey, token)
println(s"Is valid JWS : ${JWS2.verify(new RSASSAVerifier(clientPubKey.asInstanceOf[RSAPublicKey]))}")
println(s"${JWS2.getJWTClaimsSet}")
}
def getClientKeys() : (PublicKey, PrivateKey) = {
val generator = KeyPairGenerator.getInstance("RSA")
generator.initialize(2048)
val pairClient = generator.generateKeyPair
val pubKeyClient = KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(pairClient.getPublic.getEncoded))
val privateKeyClient = KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(pairClient.getPrivate.getEncoded))
(pubKeyClient, privateKeyClient)
}
def getIAdvizeKeys() : (PublicKey, PrivateKey) = {
val generator = KeyPairGenerator.getInstance("RSA")
generator.initialize(2048)
val pairIadvize = generator.generateKeyPair
val pubKeyIadvize = KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(pairIadvize.getPublic.getEncoded))
val privateKeyIadvize = KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(pairIadvize.getPrivate.getEncoded))
(pubKeyIadvize, privateKeyIadvize)
}
def createJWS(clientPrivateKey: PrivateKey) : SignedJWT = {
val claimsSet = new JWTClaimsSet.Builder()
// You can define custom claims. Here you can define your User ID which will be embed in the signed token(JWS).
// You have to prefix all the claims with `https://iadvize.com/”.
// The claim https://iadvize.com/userId is mandatory.
claimsSet.claim("https://iadvize.com/userId","c42ab96d-0637-4d1e-8be3-0a872d9d1ef1")
// For security reason it’s better to set a quick expiration time. As this token will just be used to initialise a new secured visitor session on iAdvize 1 minute seems a good duration.
claimsSet.expirationTime(ZonedDateTime.now().plusMinutes(1))
val signer = new RSASSASigner(clientPrivateKey)
val signedJWT = new SignedJWT(new JWSHeader(JWSAlgorithm.RS256), claimsSet.build())
signedJWT.sign(signer)
signedJWT
}
def createJWE(iadvizePublicKey : PublicKey, jws : SignedJWT) : JWEObject = {
val header = new JWEHeader.Builder(JWEAlgorithm.RSA_OAEP_256, EncryptionMethod.A256GCM).build()
val payload = new Payload(jws)
val jwe = new JWEObject(header, payload)
jwe.encrypt(new com.nimbusds.jose.crypto.RSAEncrypter(iadvizePublicKey.asInstanceOf[java.security.interfaces.RSAPublicKey]))
jwe
}
def decryptJWE(iadvizePrivateKey: PrivateKey, token : String): SignedJWT = {
val o = JWEObject.parse(token)
o.decrypt(new RSADecrypter(iadvizePrivateKey))
o.getPayload.toSignedJWT
}
}An example in Node.js
Last updated