From d7ebfd7a2f63e6775e067ac8c0113563eaf4af0a Mon Sep 17 00:00:00 2001 From: Joren Schipman Date: Tue, 30 Apr 2024 21:48:13 +0200 Subject: [PATCH] encrypt the initial exchange using rsa --- connectrsa.kt | 124 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 connectrsa.kt diff --git a/connectrsa.kt b/connectrsa.kt new file mode 100644 index 0000000..a625e48 --- /dev/null +++ b/connectrsa.kt @@ -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() + } + } +} +