Kotlin - RSA + AES a double layer security system

 Hello everyone, Today we will learn a double layer security system using RSA+AES, with the help of architecture visualization and one Kotlin example.

  • Encryption's primary purpose is to protect against brute force attacks. It is composed of a cipher, the message/data, and a key (the password). With a wide range of free tools available like(Aircrack-ng, John the Ripper, Rainbow Crack, L0phtCrack ), even baby hackers can attempt to hack passwords using brute force.
  • In my opinion, as a layperson in cryptography, multiple double-layer encryptions may not increase security, but it may slow down attackers.
  • Using encryption may cause performance issues. Or maybe not. It really depends on how you use it. If you understand just how "expensive" each part of your enterprise encryption operation is, it's possible you can avoid the expensive parts and dramatically increase the performance of your applications.

Let's see the architecture of the RSA + AES system


This is the top layer architecture of a double-layer security system.

We will explain the RSA + AES security system with the help of one Kotlin program, you can easily implement this algorithm on another programming platform.

Below is our demo  Kotlin driver to study the double-layer security system.

Demo.kt

import SecurityUtil.decrypt
import SecurityUtil.decryptMessagePrivateKey
import SecurityUtil.encrypt
import SecurityUtil.encryptMessageUsingPublic
import SecurityUtil.getRSAKeys
import SecurityUtil.secureRandomString
import java.security.PublicKey

import java.security.PrivateKey

/**
* @author sibinmuhammed
*/
object Demo {
@Throws(Exception::class)
@JvmStatic
fun main(args: Array<String>) {

/*
* Step 1
*
* @Client: Generate Public and Private Key
*/
val keys = getRSAKeys()
val privateKey = keys!!["private"] as PrivateKey?
val publicKey = keys["public"] as PublicKey?
println("Key Pairs generated on client-side")

/*
* Step 2
*
* @Client: Sent public key to the server and save the private key on
client local storage
*
*/println("private-key store on client-side")
println("sent public-key to server-side")

/*
* Step 3
*
* @Server: Server will generate a secure random aes_key
*/
val secure_random_aes_key = secureRandomString()
println("Generate Secure Random AES key on server-side")

/*
* Step 4
*
* @Server:Ecrypt the AES key using public key and store the AES key on
* server-side.
*/
val encrptText = encryptMessageUsingPublic(secure_random_aes_key!!, publicKey)
println("Encrypted the AES key using public key")
println("AES key stored on server")

/*
* Step 5
*
* @Server:Sent encrypted AES key to client-side
*/println("Sent encrypted AES key to client-side")

/*
* Step 6
*
* @Client: Decrypt the encrypted AES key using private key
*/
val aesKey = decryptMessagePrivateKey(encrptText, privateKey)
println("AES key successfully decrypted")

/*
* Step 7
*
* @Client:Encrypt the secrets using AES key and sent it to server-side
*/
val enc = encrypt("password-Sibin777!88", aesKey)
println("Secret succesfully encrypted")
println("Encrypted secret successfully sent to server")

/*
* Step 8
*
* @Server:Decrypt the secret using AES key
*/
val secret = decrypt(enc, aesKey)
println("Successfully decrypted, Your secret is:$secret")
}
}

If you execute this Kotlin file, you will get the following output 

Key Pairs generated on client-side
private-key store on client-side
sent public-key  to server-side
Generate Secure Random AES key on server-side
Encrypted the AES key using public key
AES key stored on server
Sent encrypted AES key to client-side
AES key successfully decrypted
Secret succesfully encrypted
Encrypted secret successfully sent to server
Successfully decrypted, Your secret is:password-Sibin777!88

Process finished with exit code 0

And you must use one Security Utility file to execute this program successfully, that is SecurityUtil.kt file.

SecurityUtil

import java.io.UnsupportedEncodingException;
import java.security.*
import java.util.Arrays;
import java.util.Base64;
import java.util.HashMap;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.security.NoSuchAlgorithmException
import java.security.MessageDigest


/**
* @author sibinmuhammed
*/
object SecurityUtil {
private var secretKey: SecretKeySpec? = null
private lateinit var key: ByteArray
private const val ASYMMETRIC_ALGORITHM = "RSA"

// set Key
fun setKey(myKey: String) {
var sha: MessageDigest? = null
try {
key = myKey.toByteArray(charset("UTF-8"))
sha = MessageDigest.getInstance("SHA-1")
key = sha.digest(key)
key = Arrays.copyOf(key, 16)
secretKey = SecretKeySpec(key, "AES")
} catch (e: NoSuchAlgorithmException) {
e.printStackTrace()
} catch (e: UnsupportedEncodingException) {
e.printStackTrace()
}
}

// method to encrypt the secret text using key
fun encrypt(strToEncrypt: String, secret: String?): String? {
try {
setKey(secret!!)
val cipher = Cipher.getInstance("AES/ECB/PKCS5Padding")
cipher.init(Cipher.ENCRYPT_MODE, secretKey)
return Base64.getEncoder().encodeToString(cipher.doFinal(strToEncrypt.
                              toByteArray(charset("UTF-8"))))
} catch (e: Exception) {
println("Error while encrypting: $e")
}
return null
}

// method to encrypt the secret text using key
fun decrypt(strToDecrypt: String?, secret: String?): String? {
try {
setKey(secret!!)
val cipher = Cipher.getInstance("AES/ECB/PKCS5PADDING")
cipher.init(Cipher.DECRYPT_MODE, secretKey)
return String(cipher.doFinal(Base64.getDecoder().decode(strToDecrypt)))
} catch (e: Exception) {
println("Error while decrypting: $e")
}
return null
}

// Get RSA keys. Uses key size of 2048.
@Throws(Exception::class)
fun getRSAKeys(): kotlin.collections.Map<String, Any>? {
val keyPairGenerator = KeyPairGenerator.getInstance("RSA")
keyPairGenerator.initialize(2048)
val keyPair = keyPairGenerator.generateKeyPair()
val privateKey = keyPair.private
val publicKey = keyPair.public
val keys: MutableMap<String, Any> = HashMap()
keys["private"] = privateKey
keys["public"] = publicKey
return keys
}

// Decrypt using RSA public key
@Throws(Exception::class)
fun decryptMessage(
encryptedText: String?,
publicKey: PublicKey?
): String? {
val cipher = Cipher.getInstance("RSA")
cipher.init(Cipher.DECRYPT_MODE, publicKey)
return String(cipher.doFinal(Base64.getDecoder().decode(encryptedText)))
}

// Encrypt using RSA private key
@Throws(Exception::class)
fun encryptMessage(
plainText: String,
privateKey: PrivateKey?
): String? {
val cipher = Cipher.getInstance("RSA")
cipher.init(Cipher.ENCRYPT_MODE, privateKey)
return Base64.getEncoder().encodeToString(cipher.doFinal(plainText.
                                  toByteArray()))
}

// Encrypt using RSA private key
@Throws(Exception::class)
fun encryptMessageUsingPublic(
plainText: String,
privateKey: PublicKey?
): String? {
val cipher = Cipher.getInstance("RSA")
cipher.init(Cipher.ENCRYPT_MODE, privateKey)
return Base64.getEncoder().encodeToString(cipher.doFinal(plainText.
                            toByteArray()))
}

// Decrypt using RSA public key
@Throws(Exception::class)
fun decryptMessagePrivateKey(
encryptedText: String?,
publicKey: PrivateKey?
): String? {
val cipher = Cipher.getInstance("RSA")
cipher.init(Cipher.DECRYPT_MODE, publicKey)
return String(cipher.doFinal(Base64.getDecoder().decode(encryptedText)))
}

//Secure Random
open fun secureRandomString(): String? {
val random = SecureRandom()
val bytes = ByteArray(20)
random.nextBytes(bytes)
val encoder = Base64.getUrlEncoder().withoutPadding()
return encoder.encodeToString(bytes)
}
}

If you have any additional comments to add please use the following comment section.


Popular posts from this blog

Spring boot video streaming example-HTML5

DataTable-Pagination example with Spring boot, jQuery and ajax

10 Best Job Posting Sites 2021-2022

Spring boot web project free download:User Registration System

Spring Boot + JPA/Hibernate One to Many mapping example

5 Hardest Puzzle,100% fail answers

Java security AES,SHA256,SHA512,MD5-Spring Boot Project Free Download

Spring Boot-AngularJS-Bootstrap-JPA-CRUD

ReactJS - Bootstrap - Buttons

Spring Boot file upload/download example