From d34deade0d8faa2ab5a3be52a8ce18108d80a4a8 Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Sat, 23 Jan 2021 18:49:34 +0600 Subject: [PATCH] temporal state (currently tools for files decryption in JS do work --- gradle.properties | 2 + tgbotapi.core/build.gradle | 6 ++- .../utils/passport/DecryptionContext.kt | 25 +++++++++ .../inmo/tgbotapi/passport/DecryptionTest.kt | 52 +++++++++++++++++++ .../passport/DecryptionContextRealization.kt | 50 ++++++++++++++++++ .../tgbotapi/passport/DecryptionTestKeys.kt | 32 ++++++++++++ .../passport/DecryptionContextRealization.kt | 40 ++++++++++++++ .../tgbotapi/passport/DecryptionTestKeys.kt | 31 +++++++++++ 8 files changed, 237 insertions(+), 1 deletion(-) create mode 100644 tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/passport/DecryptionContext.kt create mode 100644 tgbotapi.core/src/commonTest/kotlin/dev/inmo/tgbotapi/passport/DecryptionTest.kt create mode 100644 tgbotapi.core/src/jsMain/kotlin/dev/inmo/tgbotapi/utils/passport/DecryptionContextRealization.kt create mode 100644 tgbotapi.core/src/jsTest/kotlin/dev/inmo/tgbotapi/passport/DecryptionTestKeys.kt create mode 100644 tgbotapi.core/src/jvmMain/kotlin/dev/inmo/tgbotapi/utils/passport/DecryptionContextRealization.kt create mode 100644 tgbotapi.core/src/jvmTest/kotlin/dev/inmo/tgbotapi/passport/DecryptionTestKeys.kt diff --git a/gradle.properties b/gradle.properties index 5017be276e..6f5f4fb15b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -16,6 +16,8 @@ micro_utils_version=0.4.21 javax_activation_version=1.1.1 +crypto_version=1.0.1 + library_group=dev.inmo library_version=0.32.0 diff --git a/tgbotapi.core/build.gradle b/tgbotapi.core/build.gradle index dbb55557e9..937d88062d 100644 --- a/tgbotapi.core/build.gradle +++ b/tgbotapi.core/build.gradle @@ -71,12 +71,16 @@ kotlin { api "javax.activation:activation:$javax_activation_version" } } + jsMain { + dependencies { + api npm("crypto", "${crypto_version}") + } + } jvmTest { dependencies { implementation kotlin('test-junit') } } - jsTest { dependencies { implementation kotlin('test-junit') diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/passport/DecryptionContext.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/passport/DecryptionContext.kt new file mode 100644 index 0000000000..5ce250d389 --- /dev/null +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/passport/DecryptionContext.kt @@ -0,0 +1,25 @@ +package dev.inmo.tgbotapi.utils.passport + +import dev.inmo.tgbotapi.bot.TelegramBot +import dev.inmo.tgbotapi.requests.DownloadFile +import dev.inmo.tgbotapi.requests.get.GetFile +import dev.inmo.tgbotapi.types.passport.encrypted_data.PassportFile + +expect class DecryptionContext( + key: String +) { + fun ByteArray.decrypt(): ByteArray +} + +suspend fun DecryptionContext.decrypt( + file: PassportFile, + bot: TelegramBot +): ByteArray { + return bot.execute( + DownloadFile( + bot.execute( + GetFile(file.fileId) + ).filePath + ) + ).decrypt() +} diff --git a/tgbotapi.core/src/commonTest/kotlin/dev/inmo/tgbotapi/passport/DecryptionTest.kt b/tgbotapi.core/src/commonTest/kotlin/dev/inmo/tgbotapi/passport/DecryptionTest.kt new file mode 100644 index 0000000000..090ed96e02 --- /dev/null +++ b/tgbotapi.core/src/commonTest/kotlin/dev/inmo/tgbotapi/passport/DecryptionTest.kt @@ -0,0 +1,52 @@ +package dev.inmo.tgbotapi.passport + +import dev.inmo.micro_utils.crypto.decodeBase64 +import dev.inmo.tgbotapi.types.passport.EncryptedAndBase64EncodedData +import dev.inmo.tgbotapi.utils.passport.DecryptionContext +import kotlin.test.Test +import kotlin.test.assertEquals + +//expect val privateKey: String +//expect val encryptedLoremIpsum: EncryptedAndBase64EncodedData +val privateKey: String = """-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCaaMFkmMBi6Vl5 +vzy7wQjoZNLN+e9e6Lb/WBekJxfbNMt+EN9Zv7xT9xzfY68DX7v0uGoLcAqS5Mh5 +8ELiJbzg4O8dbxkggt0G+kxcbT+a3ofm1Aqhr+LkpsFh5qbLqbAHSQJAF0HPqrAc +5c6MoQVTZlWGU/j3enCcUFo7Jpsi8La6MqYboF5xGwGEZ9tOA6rMDSekr5Rdm637 +D/w4h284UX7VnqPdpZ/943VK2qvmPjm8HkFSxkSAB8RHlFyjazzm9FNOcVRGLynv +/cq7mWgyxt5nqiCG7w+lFNAFNQNvAO0rfeiTJbEzubquu4Mg31QrvLIuz+fUbsGk +ipfpN1czAgMBAAECggEAPlAoO8CpY0FoqolSqTKttZt6t0U2JMclksaqQ8TDC+Oy +e52zhTSre/ct37kK2AG6iHgj05nTqpRJk2wykbFJGDeuR+Kd8VDeggJg7qvoD0fe +8HiCEd45Yq0pPaknhulj8Iy2K8c29+eaSw8y2+3fiFi0CxG4V6dB6tNClrxtvxtl +IE85Utzmk4PLTCs010zxNVm+FwrvqlpjjhspljzleUuWE1KuldO9tNSlwUUfBr4i +BJJn4jDkQMloXoM/ArZEp7mn57N9+ZuEgVjRMCpRGEAbQI+aLCznBB1kCOY7WL8S +CwkP++SvcptaUpOjoXZZyuGU4CgBnu0+40ORbNchgQKBgQDLIbB9+WHDcZAn1g6M +8jaNDRU4HGu5vJSajFQK8Uaczg87hAxmk6R1GF0LOyoadaVmD5ax93mQxWSE/4hT +wyAPaQOFl7A/i1k/Dx/kURjRwF1sLWDFdMo/8t5bXumzrzb1bHYnHPS7S0lBAU+X +SrbIw+hv69aKawcQqdd54S1OBwKBgQDCmMarwMVn4xnOh+DOuLS4IQzPT84WgzH+ +wKw55hZGMqZ4S3JRVv256daweEbKAeR5NCccPmir0H86jwUW6WFAtxqfPWF4piVi +UD6DrUt0gWwzMGy3kbAp0hLBtsQRp/41mKuAXkvMVQ2ysInn6lmHhZvjduK8lvKh +fMRDMjxidQKBgFiciK5blI86wgTutwg7PRrI40HH/CJZJoZIwvzHBeOvbCutTe+N +ZoeCKkyU8af7PDzKfhWCfHBv+4qdIi5QB3NRfyzO4B7IPhVpFqN10RrnDJn9LaLV +cMj2vJMlU1OEErh7KQuk8QmnLPyDguHfwN7Rv1rbiYp2Z+2X+Zx8Y1QPAoGBAJIf +nq/CJXoJMou/xLP2Rt4tEy1pQ9vr0FL341vmxrsXtaGHJeSmagh861XAO4fdO+83 +llbDFl5ORft3Ad9eiETMOhVxRgwO1uuoTgkazBpERTd7GWgO4jXFJYiI8VpAx8b/ +SWkvZcOd6pdPsX6Qn4IAdjqsPz5WKwPQaJ/8zRMxAoGAGaOuyXaFZNl8IeTGYMDL +OEg9BHa+Du8jSv0vL/fCN2s/2TcvSa9uEnv8KHz59JHevvxoDNbQYlN8Ge8adFv4 +xZYQ3h/qh2ohnTUfrG4hcFUVBuv5HBdwgWhVFm5v98KQsqVzGfKorN2DemEv3/au +PFGkuu4lCPeDqu5u0dBojoA= +-----END PRIVATE KEY-----""" +val encryptedLoremIpsum = "KeuPVezTbMW4MvOGJFTAt34PRaL9iepGb1g4QEi5EQYjKXeXo7RytFOCVx6pW9O/uoMWhl+cX32kNqJVWyK7a22kuhnNT2+aiXqEpuh+madx+LK1zUvGDR1A1Mrf3fFOugcnadCQKICiqvl9cFdqsBkJQOFEs9qj5wiu1F57kekuHLWI7ZnHOojkRNq7l1aCHL0DxcLCfZW5CtWAi8g/zUE5WnGd+vUZ+hqc1vnehDul8JE8YUQbAiIxetzba9XoWouTHYZRZcNCztDbrRBYnq2UCcI5adEwQ3VNcES0lIjRuwn1BBWpvk7VOjqh+4c2tSebDX5AkqrO8XwQYwo8OwvZF+hUXFRK6QLHd4B1JQIdygCaEODG0X353upiEKJXDBqv/ZMXR9KqYZBZEfu48ZM/J6heNjVSOP4TSDrXywJgIOieu8mrQ4d7Or7Twnsu/B+bqS37PvVlfU4wHLl7ehXFj4Kusat6cIrb0R4F/Y3fL4+FcfEsk4ioEAndYBFrc1S11vo/TkcuFnXtqrr181gC5JD5LtsUH6sst36vE/JdL/UwTGqhu+rDUcgvr7FiunkasWBnzCtFs58JJrRycUKPzyKINS16GkY8yYtp7xJXBGPYOFM+J7npcKW7P41j1KceDaUArjph2yIELEXCr8qUZzWXZdrw96Te8gLi99c=" + + +class DecryptionTest { + val inputText = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." + + @Test + fun testThatDecryptionIsWorkingCorrectly() { + DecryptionContext(privateKey).apply { + val decrypted = encryptedLoremIpsum.decodeBase64().decrypt().decodeToString() + assertEquals(inputText, decrypted) + } + } +} diff --git a/tgbotapi.core/src/jsMain/kotlin/dev/inmo/tgbotapi/utils/passport/DecryptionContextRealization.kt b/tgbotapi.core/src/jsMain/kotlin/dev/inmo/tgbotapi/utils/passport/DecryptionContextRealization.kt new file mode 100644 index 0000000000..7ab9c556a1 --- /dev/null +++ b/tgbotapi.core/src/jsMain/kotlin/dev/inmo/tgbotapi/utils/passport/DecryptionContextRealization.kt @@ -0,0 +1,50 @@ +package dev.inmo.tgbotapi.utils.passport + +import dev.inmo.micro_utils.common.toArrayBuffer +import dev.inmo.micro_utils.common.toByteArray +import dev.inmo.micro_utils.crypto.encodeBase64 +import dev.inmo.micro_utils.crypto.encodeBase64String +import org.khronos.webgl.ArrayBuffer +import kotlin.js.Json +import kotlin.js.json + +private external interface InternalBuffer { + val buffer: ArrayBuffer +} + +private external object Buffer { + fun from(data: String): InternalBuffer +} + +private external interface CryptoConstants { + val RSA_PKCS1_OAEP_PADDING: Any +} +private external interface Crypto { + val constants: CryptoConstants + fun privateDecrypt( + key: Json, + data: InternalBuffer + ): InternalBuffer + fun privateEncrypt( + key: Json, + data: InternalBuffer + ) : InternalBuffer + +} + +@JsModule("crypto") +@JsNonModule +private external val crypto: Crypto + +actual class DecryptionContext actual constructor(key: String) { + private val key = json( + "key" to key, + "padding" to crypto.constants.RSA_PKCS1_OAEP_PADDING + ) + actual fun ByteArray.decrypt(): ByteArray { + return crypto.privateDecrypt( + key, + Buffer.from(encodeBase64String()) + ).buffer.toByteArray() + } +} diff --git a/tgbotapi.core/src/jsTest/kotlin/dev/inmo/tgbotapi/passport/DecryptionTestKeys.kt b/tgbotapi.core/src/jsTest/kotlin/dev/inmo/tgbotapi/passport/DecryptionTestKeys.kt new file mode 100644 index 0000000000..e82a07397c --- /dev/null +++ b/tgbotapi.core/src/jsTest/kotlin/dev/inmo/tgbotapi/passport/DecryptionTestKeys.kt @@ -0,0 +1,32 @@ +package dev.inmo.tgbotapi.passport + +import dev.inmo.tgbotapi.types.passport.EncryptedAndBase64EncodedData + +//actual val privateKey = """-----BEGIN RSA PRIVATE KEY----- +//MIIEowIBAAKCAQEAt0hdC7xyjrRAXxqrd5i06haPfKLdAvRWsPy2yWtYTFom5dBj +//atMUnFKekTwsmhKbRPBoqF7Da0RF+/Y9q9zmZv05+tNz2FEYGJ6o7r/gdAEX+pKs +//Hd84avm9RahGOwbZgcE8r8Md/tg/ZJCSMsVElzM/Gw02+U1uJQE4n/E2AATbRl0M +//oWdyXjh6Zk6HMiTCvhtQOHoMa9yI00wmHVAlZonovZSRQ2mqfwPlbkDhjsDUQMZp +//WcSPQblAd8FLcWsR1Mh86rQl1GxZVWYONaNwoeATe4p6Ng438HCL7jO7nc4jXJwp +//xqwGI9eUYlHolApBeMQK7oEYDTQ+e0iTvFryPQIDAQABAoIBAAnV81BW65rm53Fz +//H/KKGmNZlJeuscefzysuVKzYeuOWDvJUTZGFBF0jPekzXn1iNDzt3d/zPe96uXq9 +//CzA26ZJrUno4cMYSDAX+NbiiSWxQRrYmut/bg86R2mtrjWFLi86fzR7tjKWJe1Vt +//QLtCxNyMXn2YJvQYCKopt501t50mjkgR3xM375cfVmpomcZXh1K+z4ZxFVzivjvK +//ZAga3BPQ/hd6dhnwUdB/yFZFao1dDmsvJVjsnjpnWD3uqtciTeg2iqtXVLpaLfbJ +//gWOt5P94uIP5r1+qvyrrPXzUGONm4l+43zgvleEgAXWGxnutsYaFfazVQ6qOVyE7 +//fGMQfcECgYEA5Zt1fwTVoYIohq4Do/y5TnNcoj4AajXZU1OutFcPM3aNex16UPBW +//hP7Gakq3TwTKxEILDqOwo86IJuG+lX18kUwaj1f/3T0kDFvE6iLimiPYRNByog4c +//Z5Kwqn+vrnl4ciRDoz7jJsURms2PE7mYV7bndA24Gb0FZJRWiB1xI+0CgYEAzFm7 +//uTSyzacTsqorkyUFIwoGgMIE5NDBQNCVhflJcrmuHRYNwxkH9HRCXqyeHKLiNPRa +//zAoBo3WynjActoy0tFJ90qZI1203iT9BMRbPDiZEXnMH4MrWmk7e7poAUsPVKaRr +//hxvHjr2gTOLY0ClolMvnyNxZcZ/jBxAG0WwK3ZECgYEAwSkdmbQZfPwg19zBF05f +//Ho6SmbMLak7O+/jkerbbBPJxZ+eOpVTrlIs5pOYifImNg7oDz1cKHWR8yikTynN9 +//PkcF+R2RFTCAiR0S9d5PQFlzccDjD05Lux5/HZC53VA3cd7sQAOB2XXkr5TLD08N +//yI0I/mskPBL23Hymp3ANZKkCgYAO2fqttCnGjnz9ACcYk5ky+biNRQyMAKv65O3p +//BbwTzXDdBkxLwJb2ajikntEC7ceY56VtrNB/q78mhgKgNcuwS0p/s7wZhAOEQwee +//5LR5p8hSQPPyn2tHXbIQDzs0yKzGUP/LmvY+5oMu81Gkl03VephG3dTWUDN0wPJt +//5/dGMQKBgE++3BNLLV8siedqwjhSrRB/KmpbLPtoOUlRJYBfG+oITgl/d/W2NKOg +//C5GztdiZUKlHsvvcYoAAWrgEE3bKg+D7GI15yzAjQQZH6AOgL+CEnunIHBaxEEgG +//RS39yB/kPcn9ZtvcJd9v8myQnQjhco8Z2RUwb6IUIoOBvZlSGhGe +//-----END RSA PRIVATE KEY-----""" +//actual val encryptedLoremIpsum: EncryptedAndBase64EncodedData = "KeuPVezTbMW4MvOGJFTAt34PRaL9iepGb1g4QEi5EQYjKXeXo7RytFOCVx6pW9O/uoMWhl+cX32kNqJVWyK7a22kuhnNT2+aiXqEpuh+madx+LK1zUvGDR1A1Mrf3fFOugcnadCQKICiqvl9cFdqsBkJQOFEs9qj5wiu1F57kekuHLWI7ZnHOojkRNq7l1aCHL0DxcLCfZW5CtWAi8g/zUE5WnGd+vUZ+hqc1vnehDul8JE8YUQbAiIxetzba9XoWouTHYZRZcNCztDbrRBYnq2UCcI5adEwQ3VNcES0lIjRuwn1BBWpvk7VOjqh+4c2tSebDX5AkqrO8XwQYwo8OwvZF+hUXFRK6QLHd4B1JQIdygCaEODG0X353upiEKJXDBqv/ZMXR9KqYZBZEfu48ZM/J6heNjVSOP4TSDrXywJgIOieu8mrQ4d7Or7Twnsu/B+bqS37PvVlfU4wHLl7ehXFj4Kusat6cIrb0R4F/Y3fL4+FcfEsk4ioEAndYBFrc1S11vo/TkcuFnXtqrr181gC5JD5LtsUH6sst36vE/JdL/UwTGqhu+rDUcgvr7FiunkasWBnzCtFs58JJrRycUKPzyKINS16GkY8yYtp7xJXBGPYOFM+J7npcKW7P41j1KceDaUArjph2yIELEXCr8qUZzWXZdrw96Te8gLi99c=" diff --git a/tgbotapi.core/src/jvmMain/kotlin/dev/inmo/tgbotapi/utils/passport/DecryptionContextRealization.kt b/tgbotapi.core/src/jvmMain/kotlin/dev/inmo/tgbotapi/utils/passport/DecryptionContextRealization.kt new file mode 100644 index 0000000000..8a88aeb73c --- /dev/null +++ b/tgbotapi.core/src/jvmMain/kotlin/dev/inmo/tgbotapi/utils/passport/DecryptionContextRealization.kt @@ -0,0 +1,40 @@ +package dev.inmo.tgbotapi.utils.passport + +import dev.inmo.micro_utils.crypto.decodeBase64 +import sun.security.rsa.RSAPublicKeyImpl +import java.security.KeyFactory +import java.security.interfaces.RSAPrivateKey +import java.security.spec.PKCS8EncodedKeySpec +import javax.crypto.Cipher + +private val regexToRemoveFromKey = Regex("(-----(BEGIN|END) ((?:.*? KEY)|CERTIFICATE)-----|[\\s])") + +private fun String.adaptKey() { + val replaced = replace(regexToRemoveFromKey, "") + +} + +/** + * @param key PKCS8 + */ +actual class DecryptionContext actual constructor(key: String) { + private val privateKey: RSAPrivateKey = KeyFactory.getInstance("RSA").generatePrivate( + PKCS8EncodedKeySpec(key.replace(regexToRemoveFromKey, "").decodeBase64()) + ) as RSAPrivateKey + private val chunkSize: Int = privateKey.modulus.bitLength() / 8 + + actual fun ByteArray.decrypt(): ByteArray { + return Cipher.getInstance("RSA/ECB/PKCS1Padding").run { + init(Cipher.DECRYPT_MODE, privateKey) + (0 until size step chunkSize).flatMap { + val firstIndex = it + val lastIndexExclusive = if (it + chunkSize > size) { + size + } else { + it + chunkSize + } + doFinal(copyOfRange(firstIndex, lastIndexExclusive)).toList() + }.toByteArray() + } + } +} \ No newline at end of file diff --git a/tgbotapi.core/src/jvmTest/kotlin/dev/inmo/tgbotapi/passport/DecryptionTestKeys.kt b/tgbotapi.core/src/jvmTest/kotlin/dev/inmo/tgbotapi/passport/DecryptionTestKeys.kt new file mode 100644 index 0000000000..542015c3f1 --- /dev/null +++ b/tgbotapi.core/src/jvmTest/kotlin/dev/inmo/tgbotapi/passport/DecryptionTestKeys.kt @@ -0,0 +1,31 @@ +package dev.inmo.tgbotapi.passport + +//actual val privateKey: String = """-----BEGIN PRIVATE KEY----- +//MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCaaMFkmMBi6Vl5 +//vzy7wQjoZNLN+e9e6Lb/WBekJxfbNMt+EN9Zv7xT9xzfY68DX7v0uGoLcAqS5Mh5 +//8ELiJbzg4O8dbxkggt0G+kxcbT+a3ofm1Aqhr+LkpsFh5qbLqbAHSQJAF0HPqrAc +//5c6MoQVTZlWGU/j3enCcUFo7Jpsi8La6MqYboF5xGwGEZ9tOA6rMDSekr5Rdm637 +//D/w4h284UX7VnqPdpZ/943VK2qvmPjm8HkFSxkSAB8RHlFyjazzm9FNOcVRGLynv +///cq7mWgyxt5nqiCG7w+lFNAFNQNvAO0rfeiTJbEzubquu4Mg31QrvLIuz+fUbsGk +//ipfpN1czAgMBAAECggEAPlAoO8CpY0FoqolSqTKttZt6t0U2JMclksaqQ8TDC+Oy +//e52zhTSre/ct37kK2AG6iHgj05nTqpRJk2wykbFJGDeuR+Kd8VDeggJg7qvoD0fe +//8HiCEd45Yq0pPaknhulj8Iy2K8c29+eaSw8y2+3fiFi0CxG4V6dB6tNClrxtvxtl +//IE85Utzmk4PLTCs010zxNVm+FwrvqlpjjhspljzleUuWE1KuldO9tNSlwUUfBr4i +//BJJn4jDkQMloXoM/ArZEp7mn57N9+ZuEgVjRMCpRGEAbQI+aLCznBB1kCOY7WL8S +//CwkP++SvcptaUpOjoXZZyuGU4CgBnu0+40ORbNchgQKBgQDLIbB9+WHDcZAn1g6M +//8jaNDRU4HGu5vJSajFQK8Uaczg87hAxmk6R1GF0LOyoadaVmD5ax93mQxWSE/4hT +//wyAPaQOFl7A/i1k/Dx/kURjRwF1sLWDFdMo/8t5bXumzrzb1bHYnHPS7S0lBAU+X +//SrbIw+hv69aKawcQqdd54S1OBwKBgQDCmMarwMVn4xnOh+DOuLS4IQzPT84WgzH+ +//wKw55hZGMqZ4S3JRVv256daweEbKAeR5NCccPmir0H86jwUW6WFAtxqfPWF4piVi +//UD6DrUt0gWwzMGy3kbAp0hLBtsQRp/41mKuAXkvMVQ2ysInn6lmHhZvjduK8lvKh +//fMRDMjxidQKBgFiciK5blI86wgTutwg7PRrI40HH/CJZJoZIwvzHBeOvbCutTe+N +//ZoeCKkyU8af7PDzKfhWCfHBv+4qdIi5QB3NRfyzO4B7IPhVpFqN10RrnDJn9LaLV +//cMj2vJMlU1OEErh7KQuk8QmnLPyDguHfwN7Rv1rbiYp2Z+2X+Zx8Y1QPAoGBAJIf +//nq/CJXoJMou/xLP2Rt4tEy1pQ9vr0FL341vmxrsXtaGHJeSmagh861XAO4fdO+83 +//llbDFl5ORft3Ad9eiETMOhVxRgwO1uuoTgkazBpERTd7GWgO4jXFJYiI8VpAx8b/ +//SWkvZcOd6pdPsX6Qn4IAdjqsPz5WKwPQaJ/8zRMxAoGAGaOuyXaFZNl8IeTGYMDL +//OEg9BHa+Du8jSv0vL/fCN2s/2TcvSa9uEnv8KHz59JHevvxoDNbQYlN8Ge8adFv4 +//xZYQ3h/qh2ohnTUfrG4hcFUVBuv5HBdwgWhVFm5v98KQsqVzGfKorN2DemEv3/au +//PFGkuu4lCPeDqu5u0dBojoA= +//-----END PRIVATE KEY-----""" +//actual val encryptedLoremIpsum = "KeuPVezTbMW4MvOGJFTAt34PRaL9iepGb1g4QEi5EQYjKXeXo7RytFOCVx6pW9O/uoMWhl+cX32kNqJVWyK7a22kuhnNT2+aiXqEpuh+madx+LK1zUvGDR1A1Mrf3fFOugcnadCQKICiqvl9cFdqsBkJQOFEs9qj5wiu1F57kekuHLWI7ZnHOojkRNq7l1aCHL0DxcLCfZW5CtWAi8g/zUE5WnGd+vUZ+hqc1vnehDul8JE8YUQbAiIxetzba9XoWouTHYZRZcNCztDbrRBYnq2UCcI5adEwQ3VNcES0lIjRuwn1BBWpvk7VOjqh+4c2tSebDX5AkqrO8XwQYwo8OwvZF+hUXFRK6QLHd4B1JQIdygCaEODG0X353upiEKJXDBqv/ZMXR9KqYZBZEfu48ZM/J6heNjVSOP4TSDrXywJgIOieu8mrQ4d7Or7Twnsu/B+bqS37PvVlfU4wHLl7ehXFj4Kusat6cIrb0R4F/Y3fL4+FcfEsk4ioEAndYBFrc1S11vo/TkcuFnXtqrr181gC5JD5LtsUH6sst36vE/JdL/UwTGqhu+rDUcgvr7FiunkasWBnzCtFs58JJrRycUKPzyKINS16GkY8yYtp7xJXBGPYOFM+J7npcKW7P41j1KceDaUArjph2yIELEXCr8qUZzWXZdrw96Te8gLi99c="