Kotlin - RSA Encryption and Decryption example

The RSA algorithm (Rivest-Shamir-Adleman) is a cryptographic algorithm that is used for specific security services or purposes, which enables public-key encryption and is widely used to secure sensitive data, particularly when it is being sent over an insecure network such as the HTTP. A public key is shared publicly, while a private key is secret and must not be shared with anyone.
The following illustration highlights how asymmetric cryptography works:


Example 1: The Cipher Type: RSA/ECB/PKCS1Padding

import java.security.spec.PKCS8EncodedKeySpec
import javax.crypto.Cipher
import java.security.spec.X509EncodedKeySpec
import java.io.IOException
import java.security.*
import java.util.*

/*
* RSA Key Size: 1024
* Cipher Type: RSA/ECB/PKCS1Padding
*/
class RSAKotlinDemo1 {
var privateKey: PrivateKey
var publicKey: PublicKey

companion object {
// convert String publickey to Key object
@Throws(GeneralSecurityException::class, IOException::class)
fun loadPublicKey(stored: String): Key {
val data: ByteArray = Base64.getDecoder().
decode(stored.toByteArray())
val spec = X509EncodedKeySpec(data)
val fact = KeyFactory.getInstance("RSA")
return fact.generatePublic(spec)
}

// Encrypt using publickey
@Throws(Exception::class)
fun encryptMessage(plainText: String, publickey: String): String {
val cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding")
cipher.init(Cipher.ENCRYPT_MODE, loadPublicKey(publickey))
return Base64.getEncoder().encodeToString(cipher.doFinal

(plainText.toByteArray()))
}

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

// Convert String private key to privateKey object
@Throws(GeneralSecurityException::class)
fun loadPrivateKey(key64: String): PrivateKey {
val clear: ByteArray = Base64.getDecoder().
decode(key64.toByteArray())
val keySpec = PKCS8EncodedKeySpec(clear)
val fact = KeyFactory.getInstance("RSA")
val priv = fact.generatePrivate(keySpec)
Arrays.fill(clear, 0.toByte())
return priv
}

@Throws(Exception::class)
@JvmStatic
fun main(args: Array<String>) {
val secretText = "www.knowledgefactory.net"
val keyPairGenerator = RSAKotlinDemo1()
// Generate private and public key
val privateKey: String = Base64.getEncoder().

encodeToString(keyPairGenerator.privateKey.encoded)
val publicKey: String = Base64.getEncoder().

encodeToString(keyPairGenerator.publicKey.encoded)
println("Private Key: $privateKey")
println("Public Key: $publicKey")
// Encrypt secret text using public key
val encryptedValue = encryptMessage(secretText, publicKey)
println("Encrypted Value: $encryptedValue")
// Decrypt
val decryptedText = decryptMessage(encryptedValue, privateKey)
println("Decrypted output: $decryptedText")
}
}

init {
val keyGen = KeyPairGenerator.getInstance("RSA")
keyGen.initialize(1024)
val pair = keyGen.generateKeyPair()
privateKey = pair.private
publicKey = pair.public
}
}

Output:

Private  Key:

MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBANHdZHjuChS2Icoc+eUtPNLlhjZXgqPiy0o744sG/lBWdYyFamVcEBt28ExMxMtsznVrLQ9vz6V1eTNcwsuwjIfHePp4Vnedinc7U4CjqmhCY+tZab94iugJDLfh6Jbf7aDRcwuzbUK41VQwDWQcw5zcgIE0njfT3ULH/hqcSra9AgMBAAECgYBzu2CF49eBVnNJzzLr9Ed/kf2yiA3OLOqotGAmMiQaz6MhbA2heeSUEMIxgYBhIk60p/cAdUuQVjkRXw05YNINqwRuc4+/3pyNXXJ3EfyVLvjLePmdB2UFHvi+31WoXpbX1NNb8lf25G+5f58cgHsapjgWpGO9Bq2afPne1sZR4QJBAOpis/7Ytpbu68IiyukU8rNk4u+LtQXjyf3hX6NuccixSYurDTkmcPLOIJnXY9qmU2RFJjgP8bPHNo2QQyYRgVkCQQDlN8/MxNqSrZ8qSGLLJ37tCtECUnLn/tr6demUfJkLMxZI96cOi9v99DuTCISQdZDq1BS1hWNwwQ9ycuomdrAFAkApqyB6xwY28QTCv7K5GztGf0IE+h5VjLiFRQLeqCzcVABSLzermFTuJY0QLIWZAobCxbRUtSjwIBNnuWTmqKgJAkEAuvfAb0WvB+/JIYMz2oQX2yB0hhFcmvHeCmg9pBnR+DmulswzHwFj64zZP0C2aOMM1w8w6TOpfiJsCC3F4qPzRQJBAOQ6kJX8rEYAte9UI27IJ1o/JPGlatajCnHsJmzgHvkGhwqFVi9ip2DLBTAr2yRhWXnVp99tPlHTm3DY/yM/a7E=

Public Key:

MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDR3WR47goUtiHKHPnlLTzS5YY2V4Kj4stKO+OLBv5QVnWMhWplXBAbdvBMTMTLbM51ay0Pb8+ldXkzXMLLsIyHx3j6eFZ3nYp3O1OAo6poQmPrWWm/eIroCQy34eiW3+2g0XMLs21CuNVUMA1kHMOc3ICBNJ43091Cx/4anEq2vQIDAQAB

Encrypted Value:

uJ0oo4f3XbaiBUpiO49vVHKyelbdk8CIT1kOgEaiJ8XcwqM4OPZt7sHMKMWPjFE/84KQnphPdbog8uPe5DF33xNE8D5UgN+RfsUai0PQEVX07DdkiW8GnlKN0UOR8iNQoP9Dp2ir3V9pc4bKggDk7V7IxmoyP/dkbU/Jgi9OPRg=

Decrypted output: www.knowledgefactory.net 


Example 2: The Cipher Type: RSA/ECB/OAEPWithSHA-1AndMGF1Padding

import java.security.spec.PKCS8EncodedKeySpec
import javax.crypto.Cipher
import java.security.spec.X509EncodedKeySpec
import java.io.IOException
import java.security.*
import java.util.*

/*
* RSA Key Size: 2048
* Cipher Type: RSA/ECB/OAEPWithSHA-1AndMGF1Padding
*/
class RSAKotlinDemo2 {
var privateKey: PrivateKey
var publicKey: PublicKey

companion object {
// convert String publickey to Key object
@Throws(GeneralSecurityException::class, IOException::class)
fun loadPublicKey(stored: String): Key {
val data: ByteArray = Base64.getDecoder().
decode(stored.toByteArray())
val spec = X509EncodedKeySpec(data)
val fact = KeyFactory.getInstance("RSA")
return fact.generatePublic(spec)
}

// Encrypt using publickey
@Throws(Exception::class)
fun encryptMessage(plainText: String, publickey: String): String {
val cipher = Cipher.
getInstance("RSA/ECB/OAEPWithSHA-1AndMGF1Padding")
cipher.init(Cipher.ENCRYPT_MODE, loadPublicKey(publickey))
return Base64.getEncoder().encodeToString(cipher.doFinal

(plainText.toByteArray()))
}

// Decrypt using privatekey
@Throws(Exception::class)
fun decryptMessage(encryptedText: String?, privatekey: String):
String {
val cipher = Cipher.
getInstance("RSA/ECB/OAEPWithSHA-1AndMGF1Padding")
cipher.init(Cipher.DECRYPT_MODE, loadPrivateKey(privatekey))
return String(cipher.
doFinal(Base64.getDecoder().decode(encryptedText)))
}

// Convert String private key to privateKey object
@Throws(GeneralSecurityException::class)
fun loadPrivateKey(key64: String): PrivateKey {
val clear: ByteArray = Base64.getDecoder().
decode(key64.toByteArray())
val keySpec = PKCS8EncodedKeySpec(clear)
val fact = KeyFactory.getInstance("RSA")
val priv = fact.generatePrivate(keySpec)
Arrays.fill(clear, 0.toByte())
return priv
}

@Throws(Exception::class)
@JvmStatic
fun main(args: Array<String>) {
val secretText = "www.knowledgefactory.net"
val keyPairGenerator = RSAKotlinDemo2()
// Generate private and public key
val privateKey: String = Base64.getEncoder().

encodeToString(keyPairGenerator.privateKey.encoded)
val publicKey: String = Base64.getEncoder().

encodeToString(keyPairGenerator.publicKey.encoded)
println("Private Key: $privateKey")
println("Public Key: $publicKey")
// Encrypt secret text using public key
val encryptedValue = encryptMessage(secretText, publicKey)
println("Encrypted Value: $encryptedValue")
// Decrypt
val decryptedText = decryptMessage(encryptedValue, privateKey)
println("Decrypted output: $decryptedText")
}
}

init {
val keyGen = KeyPairGenerator.getInstance("RSA")
keyGen.initialize(2048)
val pair = keyGen.generateKeyPair()
privateKey = pair.private
publicKey = pair.public
}
}


Example 3: The Cipher Type: RSA/ECB/OAEPWithSHA-256AndMGF1Padding 

import java.security.spec.PKCS8EncodedKeySpec
import javax.crypto.Cipher
import java.security.spec.X509EncodedKeySpec
import java.io.IOException
import java.security.*
import java.util.*

/*
* RSA Key Size: 4096
* Cipher Type: RSA/ECB/OAEPWithSHA-256AndMGF1Padding
*/
class RSAKotlinDemo3 {
var privateKey: PrivateKey
var publicKey: PublicKey

companion object {
// convert String publickey to Key object
@Throws(GeneralSecurityException::class, IOException::class)
fun loadPublicKey(stored: String): Key {
val data: ByteArray = Base64.getDecoder().
decode(stored.toByteArray())
val spec = X509EncodedKeySpec(data)
val fact = KeyFactory.getInstance("RSA")
return fact.generatePublic(spec)
}

// Encrypt using publickey
@Throws(Exception::class)
fun encryptMessage(plainText: String, publickey: String): String {
val cipher = Cipher.
getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding")
cipher.init(Cipher.ENCRYPT_MODE, loadPublicKey(publickey))
return Base64.getEncoder().encodeToString(cipher.doFinal

(plainText.toByteArray()))
}

// Decrypt using privatekey
@Throws(Exception::class)
fun decryptMessage(encryptedText: String?, privatekey: String):
String {
val cipher = Cipher.
getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding")
cipher.init(Cipher.DECRYPT_MODE, loadPrivateKey(privatekey))
return String(cipher.
doFinal(Base64.getDecoder().decode(encryptedText)))
}

// Convert String private key to privateKey object
@Throws(GeneralSecurityException::class)
fun loadPrivateKey(key64: String): PrivateKey {
val clear: ByteArray = Base64.getDecoder().
decode(key64.toByteArray())
val keySpec = PKCS8EncodedKeySpec(clear)
val fact = KeyFactory.getInstance("RSA")
val priv = fact.generatePrivate(keySpec)
Arrays.fill(clear, 0.toByte())
return priv
}

@Throws(Exception::class)
@JvmStatic
fun main(args: Array<String>) {
val secretText = "www.knowledgefactory.net"
val keyPairGenerator = RSAKotlinDemo3()
// Generate private and public key
val privateKey: String = Base64.getEncoder().

encodeToString(keyPairGenerator.privateKey.encoded)
val publicKey: String = Base64.getEncoder().

encodeToString(keyPairGenerator.publicKey.encoded)
println("Private Key: $privateKey")
println("Public Key: $publicKey")
// Encrypt secret text using public key
val encryptedValue = encryptMessage(secretText, publicKey)
println("Encrypted Value: $encryptedValue")
// Decrypt
val decryptedText = decryptMessage(encryptedValue, privateKey)
println("Decrypted output: $decryptedText")
}
}

init {
val keyGen = KeyPairGenerator.getInstance("RSA")
keyGen.initialize(4096)
val pair = keyGen.generateKeyPair()
privateKey = pair.private
publicKey = pair.public
}
}

More Kotlin related topics,

Popular posts from this blog

Learn Java 8 streams with an example - print odd/even numbers from Array and List

Java Stream API - How to convert List of objects to another List of objects using Java streams?

Registration and Login with Spring Boot + Spring Security + Thymeleaf

Java, Spring Boot Mini Project - Library Management System - Download

ReactJS, Spring Boot JWT Authentication Example

Spring Boot + Mockito simple application with 100% code coverage

Top 5 Java ORM tools - 2024

Java - Blowfish Encryption and decryption Example

Spring boot video streaming example-HTML5

Google Cloud Storage + Spring Boot - File Upload, Download, and Delete