encrypt the initial exchange using rsa

This commit is contained in:
Joren Schipman 2024-04-30 21:48:13 +02:00
parent 014245edc7
commit d7ebfd7a2f
Signed by untrusted user who does not match committer: Joren
GPG Key ID: 280E33DFBC0F1B55

124
connectrsa.kt Normal file
View File

@ -0,0 +1,124 @@
package com.ti.mobpo.ui.util
import kotlinx.coroutines.CoroutineStart
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import okio.ByteString.Companion.encode
import okio.ByteString.Companion.toByteString
import java.io.BufferedReader
import java.io.InputStreamReader
import java.io.PrintWriter
import java.net.Socket
import java.nio.charset.Charset
import java.security.KeyFactory
import java.security.PublicKey
import java.security.SecureRandom
import java.security.spec.X509EncodedKeySpec
import javax.crypto.Cipher
import javax.crypto.spec.IvParameterSpec
import javax.crypto.spec.SecretKeySpec
import kotlin.io.encoding.Base64
class Connect {
companion object {
private const val RSA_ALGORITHM = "RSA"
private const val CIPHER_TYPE_FOR_RSA = "RSA/ECB/PKCS1Padding"
private val keyFactory = KeyFactory.getInstance(RSA_ALGORITHM)
private val cipher = Cipher.getInstance(CIPHER_TYPE_FOR_RSA)
fun decodeBase64(input: String): ByteArray {
return android.util.Base64.decode(input, android.util.Base64.DEFAULT)
}
fun encodeBase64(input: ByteArray): String {
return android.util.Base64.encodeToString(input, android.util.Base64.DEFAULT)
}
fun decrypt(algorithm: String, cipherText: String, key: SecretKeySpec, iv: IvParameterSpec): String {
val cipher = Cipher.getInstance(algorithm)
cipher.init(Cipher.DECRYPT_MODE, key, iv)
val plainText = cipher.doFinal(decodeBase64(cipherText))
return String(plainText)
}
fun encrypt(algorithm: String, inputText: String, key: SecretKeySpec, iv: IvParameterSpec): String {
val cipher = Cipher.getInstance(algorithm)
cipher.init(Cipher.ENCRYPT_MODE, key, iv)
val cipherText = cipher.doFinal(inputText.toByteArray())
return encodeBase64(cipherText)
}
fun getPublicKeyFromString(publicKeyString: String): PublicKey? =
try {
val keySpec =
X509EncodedKeySpec(decodeBase64(publicKeyString))
keyFactory.generatePublic(keySpec)
} catch (exception: Exception) {
exception.printStackTrace()
null
}
fun encryptText(plainText: String, publicKey: PublicKey): String? =
try {
cipher.init(Cipher.ENCRYPT_MODE, publicKey)
encodeBase64(cipher.doFinal(plainText.toByteArray())).lines().joinToString("")
} catch (exception: Exception) {
exception.printStackTrace()
null
}
@OptIn(ExperimentalStdlibApi::class)
fun main() {
val pKey = getPublicKeyFromString("MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu09x4q24cMSJZmxMGSzRoL3jXG3kguVbBV6zRnPZwPT9nIofs7yb4lh6/deNedNJssLYJEmiAyI3NzsvLzihipCjatAYEgLgRcF60HBrqUKwT6uxukoVbXi+c9O70CjDEJEKDSW/ps5d6cAOMq5KmoGe4f+Geo5Nzxwjdhlaw/wjY1r5S/C7c5JRMSTn5xYwRZJFM4zRSOEz8d02FemLLWQggvRV7bIJuk1w0039sO/RjWTOeMqNPXXaBH6jV6seDCJ4coXWv0g4xNwCrxNtm1aRFW3zyh3GhAEVXcOmJ5EOUL6EiKt+5RTtSdL7OKHv+RfQuv4pkmlqpPo8pQHvnQIDAQAB")!!
println(encryptText("Hi", pKey))
val host = "192.168.90.151"
val port = 8080
val secureRandom = SecureRandom()
val keyBytes = ByteArray(16)
val ivBytes = ByteArray(16)
secureRandom.nextBytes(keyBytes)
secureRandom.nextBytes(ivBytes)
val key = SecretKeySpec(keyBytes, "AES")
val iv = IvParameterSpec(ivBytes)
val algorithm = "AES/CBC/PKCS5Padding"
var sendData = "Hello, World!"
val chunkSize = 45
val chunks = sendData.chunked(chunkSize)
val socket = Socket(host, port)
val writer = PrintWriter(socket.getOutputStream(), true)
val reader = BufferedReader(InputStreamReader(socket.getInputStream()))
val encodedKey = encodeBase64(keyBytes)
println(encryptText(encodedKey, pKey))
writer.println(encryptText(encodedKey, pKey))
reader.readLine()
val encodedIV = encodeBase64(ivBytes)
println(encryptText(encodedIV,pKey))
writer.println(encryptText(encodedIV, pKey))
reader.readLine()
for (chunk in chunks) {
val cipherText = encrypt(algorithm, chunk, key, iv)
writer.println(cipherText)
reader.readLine()
}
writer.println("END_OF_COMMUNICATION")
reader.readLine()
println("Client: Ready for next operation")
writer.println("Ready for next operation")
reader.readLine()
// Close resources
writer.close()
reader.close()
socket.close()
}
}
}