diff --git a/mirai-core/src/androidMain/kotlin/net/mamoe/mirai/utils/cryptor/ECDHAndroid.kt b/mirai-core/src/androidMain/kotlin/net/mamoe/mirai/utils/cryptor/ECDHAndroid.kt index c5b1df78a..b6b5a6a93 100644 --- a/mirai-core/src/androidMain/kotlin/net/mamoe/mirai/utils/cryptor/ECDHAndroid.kt +++ b/mirai-core/src/androidMain/kotlin/net/mamoe/mirai/utils/cryptor/ECDHAndroid.kt @@ -11,6 +11,7 @@ package net.mamoe.mirai.utils.cryptor import android.annotation.SuppressLint import net.mamoe.mirai.utils.MiraiInternalAPI +import net.mamoe.mirai.utils.MiraiLogger import net.mamoe.mirai.utils.MiraiPlatformUtils.md5 import java.security.* import java.security.spec.ECGenParameterSpec @@ -40,28 +41,40 @@ actual class ECDH actual constructor(actual val keyPair: ECDHKeyPair) { actual val isECDHAvailable: Boolean get() = _isECDHAvailable init { - kotlin.runCatching { - @SuppressLint("PrivateApi") - val clazz = Class.forName( - "com.android.org.bouncycastle.jce.provider.BouncyCastleProvider", - true, - ClassLoader.getSystemClassLoader() - ) - - val providerName = clazz.getDeclaredField("PROVIDER_NAME").get(null) as String - - if (Security.getProvider(providerName) != null) { - Security.removeProvider(providerName) + fun testECDH() { + ECDHKeyPairImpl( + KeyPairGenerator.getInstance("ECDH") + .also { it.initialize(ECGenParameterSpec("secp192k1")) } + .genKeyPair()).let { + calculateShareKey(it.privateKey, it.publicKey) } - Security.addProvider(clazz.newInstance() as Provider) - generateKeyPair() - _isECDHAvailable = true - }.exceptionOrNull()?.let { - throw IllegalStateException("cannot init BouncyCastle", it) } - _isECDHAvailable = false - } + @SuppressLint("PrivateApi") + if (kotlin.runCatching { testECDH() }.isFailure) { + kotlin.runCatching { + val providerName = "BC" + + if (Security.getProvider(providerName) != null) { + Security.removeProvider(providerName) + } + @Suppress("SpellCheckingInspection") + Security.addProvider( + Class.forName( + "com.android.org.bouncycastle.jce.provider.BouncyCastleProvider", + true, + ClassLoader.getSystemClassLoader() + ).newInstance() as Provider + ) + testECDH() + _isECDHAvailable = true + }.exceptionOrNull()?.let { + _isECDHAvailable = false + @Suppress("DEPRECATION") + MiraiLogger.error(it) + } + } + } actual fun generateKeyPair(): ECDHKeyPair { if (!isECDHAvailable) { diff --git a/mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/utils/cryptor/ECDHJvm.kt b/mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/utils/cryptor/ECDHJvm.kt index 3db9de92b..0cb60c7e9 100644 --- a/mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/utils/cryptor/ECDHJvm.kt +++ b/mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/utils/cryptor/ECDHJvm.kt @@ -35,20 +35,30 @@ actual fun ECDH() = ECDH(ECDH.generateKeyPair()) actual class ECDH actual constructor(actual val keyPair: ECDHKeyPair) { actual companion object { - @Suppress("ObjectPropertyName") - private val _isECDHAvailable: Boolean = kotlin.runCatching { - if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) != null) { - Security.removeProvider(BouncyCastleProvider.PROVIDER_NAME) - } - Security.addProvider(BouncyCastleProvider()) - ECDHKeyPairImpl(KeyPairGenerator.getInstance("ECDH") - .also { it.initialize(ECGenParameterSpec("secp192k1")) } - .genKeyPair()).let { - calculateShareKey(it.privateKey, it.publicKey) - } // try if it is working - }.isSuccess + actual val isECDHAvailable: Boolean - actual val isECDHAvailable: Boolean get() = _isECDHAvailable + init { + isECDHAvailable = kotlin.runCatching { + fun testECDH() { + ECDHKeyPairImpl( + KeyPairGenerator.getInstance("ECDH") + .also { it.initialize(ECGenParameterSpec("secp192k1")) } + .genKeyPair()).let { + calculateShareKey(it.privateKey, it.publicKey) + } + } + + if (kotlin.runCatching { testECDH() }.isSuccess) { + return@runCatching + } + + if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) != null) { + Security.removeProvider(BouncyCastleProvider.PROVIDER_NAME) + } + Security.addProvider(BouncyCastleProvider()) + testECDH() + }.isSuccess + } actual fun generateKeyPair(): ECDHKeyPair { if (!isECDHAvailable) {