mirror of
https://github.com/InsanusMokrassar/TelegramBotAPI.git
synced 2024-11-22 08:13:47 +00:00
complete tools for handling of encrypted data
This commit is contained in:
parent
d34deade0d
commit
4d63e3a17d
@ -16,8 +16,6 @@ micro_utils_version=0.4.21
|
|||||||
|
|
||||||
javax_activation_version=1.1.1
|
javax_activation_version=1.1.1
|
||||||
|
|
||||||
crypto_version=1.0.1
|
|
||||||
|
|
||||||
library_group=dev.inmo
|
library_group=dev.inmo
|
||||||
library_version=0.32.0
|
library_version=0.32.0
|
||||||
|
|
||||||
|
@ -71,11 +71,6 @@ kotlin {
|
|||||||
api "javax.activation:activation:$javax_activation_version"
|
api "javax.activation:activation:$javax_activation_version"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
jsMain {
|
|
||||||
dependencies {
|
|
||||||
api npm("crypto", "${crypto_version}")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
jvmTest {
|
jvmTest {
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation kotlin('test-junit')
|
implementation kotlin('test-junit')
|
||||||
|
@ -4,14 +4,15 @@ import dev.inmo.tgbotapi.bot.TelegramBot
|
|||||||
import dev.inmo.tgbotapi.requests.DownloadFile
|
import dev.inmo.tgbotapi.requests.DownloadFile
|
||||||
import dev.inmo.tgbotapi.requests.get.GetFile
|
import dev.inmo.tgbotapi.requests.get.GetFile
|
||||||
import dev.inmo.tgbotapi.types.passport.encrypted_data.PassportFile
|
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(
|
interface Decryptor {
|
||||||
key: String
|
|
||||||
) {
|
|
||||||
fun ByteArray.decrypt(): ByteArray
|
fun ByteArray.decrypt(): ByteArray
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun DecryptionContext.decrypt(
|
suspend fun Decryptor.decrypt(
|
||||||
file: PassportFile,
|
file: PassportFile,
|
||||||
bot: TelegramBot
|
bot: TelegramBot
|
||||||
): ByteArray {
|
): ByteArray {
|
||||||
@ -23,3 +24,9 @@ suspend fun DecryptionContext.decrypt(
|
|||||||
)
|
)
|
||||||
).decrypt()
|
).decrypt()
|
||||||
}
|
}
|
||||||
|
fun Decryptor.decryptData(
|
||||||
|
data: WithData
|
||||||
|
) = nonstrictJsonFormat.decodeFromString(
|
||||||
|
JsonObject.serializer(),
|
||||||
|
data.data.encodeToByteArray().decrypt().decodeToString()
|
||||||
|
)
|
||||||
|
@ -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()
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,7 +1,6 @@
|
|||||||
package dev.inmo.tgbotapi.utils.passport
|
package dev.inmo.tgbotapi.utils.passport
|
||||||
|
|
||||||
import dev.inmo.micro_utils.crypto.decodeBase64
|
import dev.inmo.micro_utils.crypto.decodeBase64
|
||||||
import sun.security.rsa.RSAPublicKeyImpl
|
|
||||||
import java.security.KeyFactory
|
import java.security.KeyFactory
|
||||||
import java.security.interfaces.RSAPrivateKey
|
import java.security.interfaces.RSAPrivateKey
|
||||||
import java.security.spec.PKCS8EncodedKeySpec
|
import java.security.spec.PKCS8EncodedKeySpec
|
||||||
@ -9,21 +8,16 @@ import javax.crypto.Cipher
|
|||||||
|
|
||||||
private val regexToRemoveFromKey = Regex("(-----(BEGIN|END) ((?:.*? KEY)|CERTIFICATE)-----|[\\s])")
|
private val regexToRemoveFromKey = Regex("(-----(BEGIN|END) ((?:.*? KEY)|CERTIFICATE)-----|[\\s])")
|
||||||
|
|
||||||
private fun String.adaptKey() {
|
|
||||||
val replaced = replace(regexToRemoveFromKey, "")
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param key PKCS8
|
* @param key PKCS8
|
||||||
*/
|
*/
|
||||||
actual class DecryptionContext actual constructor(key: String) {
|
class PKCS8Decryptor (key: String): Decryptor {
|
||||||
private val privateKey: RSAPrivateKey = KeyFactory.getInstance("RSA").generatePrivate(
|
private val privateKey: RSAPrivateKey = KeyFactory.getInstance("RSA").generatePrivate(
|
||||||
PKCS8EncodedKeySpec(key.replace(regexToRemoveFromKey, "").decodeBase64())
|
PKCS8EncodedKeySpec(key.replace(regexToRemoveFromKey, "").decodeBase64())
|
||||||
) as RSAPrivateKey
|
) as RSAPrivateKey
|
||||||
private val chunkSize: Int = privateKey.modulus.bitLength() / 8
|
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 {
|
return Cipher.getInstance("RSA/ECB/PKCS1Padding").run {
|
||||||
init(Cipher.DECRYPT_MODE, privateKey)
|
init(Cipher.DECRYPT_MODE, privateKey)
|
||||||
(0 until size step chunkSize).flatMap {
|
(0 until size step chunkSize).flatMap {
|
||||||
@ -37,4 +31,9 @@ actual class DecryptionContext actual constructor(key: String) {
|
|||||||
}.toByteArray()
|
}.toByteArray()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun Decryptor(key: String) = PKCS8Decryptor(key)
|
||||||
|
|
||||||
|
inline fun <T> doWithDecryptor(decryptor: Decryptor, crossinline block: Decryptor.() -> T) = decryptor.run(block)
|
||||||
|
inline fun <T> doWithDecryptor(key: String, crossinline block: Decryptor.() -> T) = doWithDecryptor(Decryptor(key), block)
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package dev.inmo.tgbotapi.passport
|
package dev.inmo.tgbotapi.passport
|
||||||
|
|
||||||
import dev.inmo.micro_utils.crypto.decodeBase64
|
import dev.inmo.micro_utils.crypto.decodeBase64
|
||||||
import dev.inmo.tgbotapi.types.passport.EncryptedAndBase64EncodedData
|
import dev.inmo.tgbotapi.utils.passport.Decryptor
|
||||||
import dev.inmo.tgbotapi.utils.passport.DecryptionContext
|
import dev.inmo.tgbotapi.utils.passport.doWithDecryptor
|
||||||
import kotlin.test.Test
|
import kotlin.test.Test
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
@ -44,7 +44,7 @@ class DecryptionTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testThatDecryptionIsWorkingCorrectly() {
|
fun testThatDecryptionIsWorkingCorrectly() {
|
||||||
DecryptionContext(privateKey).apply {
|
doWithDecryptor(privateKey) {
|
||||||
val decrypted = encryptedLoremIpsum.decodeBase64().decrypt().decodeToString()
|
val decrypted = encryptedLoremIpsum.decodeBase64().decrypt().decodeToString()
|
||||||
assertEquals(inputText, decrypted)
|
assertEquals(inputText, decrypted)
|
||||||
}
|
}
|
@ -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="
|
|
Loading…
Reference in New Issue
Block a user