start adding signature and encryption

This commit is contained in:
gowthaman.b
2023-11-12 08:25:52 +05:30
parent 1a22043cf2
commit 10813529f2
9 changed files with 254 additions and 64 deletions

View File

@@ -1,9 +1,7 @@
package com.restapi.domain
import com.fasterxml.jackson.databind.DeserializationFeature
import com.fasterxml.jackson.databind.Module
import com.fasterxml.jackson.databind.SerializationFeature
import com.fasterxml.jackson.databind.module.SimpleModule
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import com.restapi.config.AppConfig.Companion.appConfig
import com.restapi.config.AuthUser
@@ -13,26 +11,138 @@ import io.ebean.config.CurrentTenantProvider
import io.ebean.config.CurrentUserProvider
import io.ebean.config.DatabaseConfig
import io.ebean.config.TenantMode
import org.bouncycastle.openssl.jcajce.JcaPEMWriter
import org.bouncycastle.util.io.pem.PemReader
import org.jose4j.jwk.PublicJsonWebKey
import org.jose4j.jwk.RsaJsonWebKey
import org.jose4j.jwk.RsaJwkGenerator
import org.jose4j.jws.AlgorithmIdentifiers
import org.jose4j.jws.JsonWebSignature
import org.slf4j.LoggerFactory
import redis.clients.jedis.JedisPooled
import java.io.StringReader
import java.io.StringWriter
import java.security.KeyFactory
import java.security.interfaces.RSAPrivateKey
import java.security.interfaces.RSAPublicKey
import java.security.spec.PKCS8EncodedKeySpec
import java.security.spec.X509EncodedKeySpec
import java.util.*
import kotlin.jvm.optionals.getOrDefault
object Session {
private val KEY_ID = "${appConfig.appName()}-KEY"
private val logger = LoggerFactory.getLogger("session")
private val currentUser = object : ThreadLocal<AuthUser>() {
override fun initialValue(): AuthUser {
return AuthUser("", "", emptyList<String>())
}
}
fun setAuthorizedUser(a: AuthUser) = currentUser.set(a)
//if not passed in ENV, then we shall generate and print
private fun makeRsaJsonWebKey(publicKey: String, privateKey: String): RsaJsonWebKey {
val newPublicKey = readPublicKey(publicKey)
val newPrivateKey = readPrivateKey(privateKey)
val rsa = PublicJsonWebKey.Factory.newPublicJwk(newPublicKey) as RsaJsonWebKey
rsa.privateKey = newPrivateKey
rsa.keyId = KEY_ID
return rsa
}
private val keyFactory = KeyFactory.getInstance("RSA")
private fun readPublicKey(file: String): RSAPublicKey {
StringReader(file).use { keyReader ->
PemReader(keyReader).use { pemReader ->
val pemObject = pemReader.readPemObject()
val content = pemObject.content
val pubKeySpec = X509EncodedKeySpec(content)
return keyFactory.generatePublic(pubKeySpec) as RSAPublicKey
}
}
}
private fun readPrivateKey(file: String): RSAPrivateKey {
StringReader(file).use { keyReader ->
PemReader(keyReader).use { pemReader ->
val pemObject = pemReader.readPemObject()
val content = pemObject.content
val privKeySpec = PKCS8EncodedKeySpec(content)
return keyFactory.generatePrivate(privKeySpec) as RSAPrivateKey
}
}
}
private val keypair: RsaJsonWebKey by lazy {
if (appConfig.privateKey().isPresent && appConfig.publicKey().isPresent) {
makeRsaJsonWebKey(
appConfig.publicKey().get(),
appConfig.privateKey().get()
)
} else {
RsaJwkGenerator.generateJwk(2048).apply {
keyId = KEY_ID
logger.warn("Save this PrivateKey/PublicKey and pass it in the Config File from next time")
StringWriter().use { s ->
JcaPEMWriter(s).use { p ->
p.writeObject(privateKey)
}
logger.warn("Private Key\n${s.toString()}")
}
StringWriter().use { s ->
JcaPEMWriter(s).use { p ->
p.writeObject(publicKey)
}
logger.warn("Public Key\n${s.toString()}")
}
}
}
}
fun sign(payload: String): String {
// Create a new JsonWebSignature
val jws = JsonWebSignature()
// Set the payload, or signed content, on the JWS object
jws.setPayload(payload)
// Set the signature algorithm on the JWS that will integrity protect the payload
jws.algorithmHeaderValue = AlgorithmIdentifiers.RSA_PSS_USING_SHA512
// Set the signing key on the JWS
// Note that your application will need to determine where/how to get the key
// and here we just use an example from the JWS spec
jws.setKey(keypair.privateKey)
// Sign the JWS and produce the compact serialization or complete JWS representation, which
// is a string consisting of three dot ('.') separated base64url-encoded
// parts in the form Header.Payload.Signature
return jws.getCompactSerialization()
}
private val sc = DatabaseConfig().apply {
loadFromProperties(Properties().apply {
setProperty("datasource.db.username", appConfig.dbUser())
setProperty("datasource.db.password", appConfig.dbPass())
setProperty("datasource.db.url", appConfig.dbUrl())
setProperty("ebean.migration.run", appConfig.dbRunMigration().toString())
if(appConfig.seedSqlFile().isPresent){
if (appConfig.seedSqlFile().isPresent) {
setProperty("ebean.ddl.seedSql", appConfig.seedSqlFile().get())
}
})