encrypt the initial exchange using rsa
This commit is contained in:
		
							
								
								
									
										124
									
								
								connectrsa.kt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										124
									
								
								connectrsa.kt
									
									
									
									
									
										Normal 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()
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Reference in New Issue
	
	Block a user