From 4d63e3a17db821f21fcc1f660a64976fba96f570 Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Sat, 23 Jan 2021 20:50:40 +0600 Subject: [PATCH] complete tools for handling of encrypted data --- gradle.properties | 2 - tgbotapi.core/build.gradle | 5 -- .../utils/passport/DecryptionContext.kt | 15 ++++-- .../passport/DecryptionContextRealization.kt | 50 ------------------- .../passport/DecryptionContextRealization.kt | 17 +++---- .../inmo/tgbotapi/passport/DecryptionTest.kt | 6 +-- .../tgbotapi/passport/DecryptionTestKeys.kt | 31 ------------ 7 files changed, 22 insertions(+), 104 deletions(-) delete mode 100644 tgbotapi.core/src/jsMain/kotlin/dev/inmo/tgbotapi/utils/passport/DecryptionContextRealization.kt rename tgbotapi.core/src/{commonTest => jvmTest}/kotlin/dev/inmo/tgbotapi/passport/DecryptionTest.kt (95%) delete mode 100644 tgbotapi.core/src/jvmTest/kotlin/dev/inmo/tgbotapi/passport/DecryptionTestKeys.kt diff --git a/gradle.properties b/gradle.properties index 6f5f4fb15b..5017be276e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -16,8 +16,6 @@ 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 937d88062d..1894298a2a 100644 --- a/tgbotapi.core/build.gradle +++ b/tgbotapi.core/build.gradle @@ -71,11 +71,6 @@ kotlin { api "javax.activation:activation:$javax_activation_version" } } - jsMain { - dependencies { - api npm("crypto", "${crypto_version}") - } - } jvmTest { 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 index 5ce250d389..425970e31e 100644 --- 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 @@ -4,14 +4,15 @@ 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 +import dev.inmo.tgbotapi.types.passport.encrypted_data.abstracts.WithData +import dev.inmo.tgbotapi.utils.nonstrictJsonFormat +import kotlinx.serialization.json.JsonObject -expect class DecryptionContext( - key: String -) { +interface Decryptor { fun ByteArray.decrypt(): ByteArray } -suspend fun DecryptionContext.decrypt( +suspend fun Decryptor.decrypt( file: PassportFile, bot: TelegramBot ): ByteArray { @@ -23,3 +24,9 @@ suspend fun DecryptionContext.decrypt( ) ).decrypt() } +fun Decryptor.decryptData( + data: WithData +) = nonstrictJsonFormat.decodeFromString( + JsonObject.serializer(), + data.data.encodeToByteArray().decrypt().decodeToString() +) 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 deleted file mode 100644 index 7ab9c556a1..0000000000 --- a/tgbotapi.core/src/jsMain/kotlin/dev/inmo/tgbotapi/utils/passport/DecryptionContextRealization.kt +++ /dev/null @@ -1,50 +0,0 @@ -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/jvmMain/kotlin/dev/inmo/tgbotapi/utils/passport/DecryptionContextRealization.kt b/tgbotapi.core/src/jvmMain/kotlin/dev/inmo/tgbotapi/utils/passport/DecryptionContextRealization.kt index 8a88aeb73c..402a295a99 100644 --- 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 @@ -1,7 +1,6 @@ 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 @@ -9,21 +8,16 @@ 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) { +class PKCS8Decryptor (key: String): Decryptor { 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 { + override fun ByteArray.decrypt(): ByteArray { return Cipher.getInstance("RSA/ECB/PKCS1Padding").run { init(Cipher.DECRYPT_MODE, privateKey) (0 until size step chunkSize).flatMap { @@ -37,4 +31,9 @@ actual class DecryptionContext actual constructor(key: String) { }.toByteArray() } } -} \ No newline at end of file +} + +fun Decryptor(key: String) = PKCS8Decryptor(key) + +inline fun doWithDecryptor(decryptor: Decryptor, crossinline block: Decryptor.() -> T) = decryptor.run(block) +inline fun doWithDecryptor(key: String, crossinline block: Decryptor.() -> T) = doWithDecryptor(Decryptor(key), block) diff --git a/tgbotapi.core/src/commonTest/kotlin/dev/inmo/tgbotapi/passport/DecryptionTest.kt b/tgbotapi.core/src/jvmTest/kotlin/dev/inmo/tgbotapi/passport/DecryptionTest.kt similarity index 95% rename from tgbotapi.core/src/commonTest/kotlin/dev/inmo/tgbotapi/passport/DecryptionTest.kt rename to tgbotapi.core/src/jvmTest/kotlin/dev/inmo/tgbotapi/passport/DecryptionTest.kt index 090ed96e02..7f9562bffb 100644 --- a/tgbotapi.core/src/commonTest/kotlin/dev/inmo/tgbotapi/passport/DecryptionTest.kt +++ b/tgbotapi.core/src/jvmTest/kotlin/dev/inmo/tgbotapi/passport/DecryptionTest.kt @@ -1,8 +1,8 @@ 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 dev.inmo.tgbotapi.utils.passport.Decryptor +import dev.inmo.tgbotapi.utils.passport.doWithDecryptor import kotlin.test.Test import kotlin.test.assertEquals @@ -44,7 +44,7 @@ class DecryptionTest { @Test fun testThatDecryptionIsWorkingCorrectly() { - DecryptionContext(privateKey).apply { + doWithDecryptor(privateKey) { val decrypted = encryptedLoremIpsum.decodeBase64().decrypt().decodeToString() assertEquals(inputText, decrypted) } 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 deleted file mode 100644 index 542015c3f1..0000000000 --- a/tgbotapi.core/src/jvmTest/kotlin/dev/inmo/tgbotapi/passport/DecryptionTestKeys.kt +++ /dev/null @@ -1,31 +0,0 @@ -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="