From 02e0df2d64e71e455df78ecffe991af59e9648cc Mon Sep 17 00:00:00 2001 From: Luna712 <142361265+Luna712@users.noreply.github.com> Date: Mon, 29 Jun 2026 14:15:31 -0600 Subject: [PATCH 01/12] Use cryptography-kotlin in the app itself also --- .../com/lagradost/cloudstream3/plugins/VotingApi.kt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/com/lagradost/cloudstream3/plugins/VotingApi.kt b/app/src/main/java/com/lagradost/cloudstream3/plugins/VotingApi.kt index 0ceaa77e566..83248f970a3 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/plugins/VotingApi.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/plugins/VotingApi.kt @@ -7,9 +7,10 @@ import com.lagradost.cloudstream3.CloudStreamApp.Companion.context import com.lagradost.cloudstream3.CloudStreamApp.Companion.getKey import com.lagradost.cloudstream3.CloudStreamApp.Companion.setKey import com.lagradost.cloudstream3.R -import java.security.MessageDigest import com.lagradost.cloudstream3.app import com.lagradost.cloudstream3.utils.Coroutines.main +import dev.whyoleg.cryptography.CryptographyProvider +import dev.whyoleg.cryptography.algorithms.SHA256 import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock import kotlinx.serialization.SerialName @@ -19,10 +20,9 @@ object VotingApi { private const val LOGKEY = "VotingApi" private const val API_DOMAIN = "https://api.countify.xyz" - private fun transformUrl(url: String): String = - MessageDigest - .getInstance("SHA-256") - .digest("${url}#funny-salt".toByteArray()) + private suspend fun transformUrl(url: String): String = + CryptographyProvider.Default.get(SHA256) + .hasher().hash("$url#funny-salt".encodeToByteArray()) .fold("") { str, it -> str + "%02x".format(it) } suspend fun SitePlugin.getVotes(): Int = getVotes(url) From 1b0fca9d08cbebb342a3b7c3e336bf6a2410c576 Mon Sep 17 00:00:00 2001 From: Luna712 <142361265+Luna712@users.noreply.github.com> Date: Mon, 29 Jun 2026 14:17:04 -0600 Subject: [PATCH 02/12] Add --- app/build.gradle.kts | 1 + 1 file changed, 1 insertion(+) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 75a9698c8c4..f00d14cfaf2 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -275,6 +275,7 @@ dependencies { implementation(libs.conscrypt.android) // To Fix SSL Fu*kery on Android 9 implementation(libs.jackson.module.kotlin) // JSON Parser implementation(libs.zipline) + implementation(libs.bundles.cryptography) // Cryptography // Deprecated; will be removed once extensions have time to migrate from using it implementation("me.xdrop:fuzzywuzzy:1.4.0") From a82713c41de938a0d371428b5554cf1295999f39 Mon Sep 17 00:00:00 2001 From: Luna712 <142361265+Luna712@users.noreply.github.com> Date: Mon, 29 Jun 2026 14:24:54 -0600 Subject: [PATCH 03/12] Update --- .../com/lagradost/cloudstream3/syncproviders/AuthAPI.kt | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/com/lagradost/cloudstream3/syncproviders/AuthAPI.kt b/app/src/main/java/com/lagradost/cloudstream3/syncproviders/AuthAPI.kt index 60e41e8b3d5..9646c398765 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/syncproviders/AuthAPI.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/syncproviders/AuthAPI.kt @@ -8,12 +8,12 @@ import com.lagradost.cloudstream3.APIHolder.unixTimeMS import com.lagradost.cloudstream3.base64Encode import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.APP_STRING import com.lagradost.cloudstream3.utils.AppContextUtils.splitQuery +import dev.whyoleg.cryptography.random.CryptographyRandom import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable import kotlinx.serialization.json.JsonNames import java.net.URI -import java.security.SecureRandom data class AuthLoginPage( /** The website to open to authenticate */ @@ -182,9 +182,7 @@ abstract class AuthAPI { fun generateCodeVerifier(): String { // It is recommended to use a URL-safe string as code_verifier. // See section 4 of RFC 7636 for more details. - val secureRandom = SecureRandom() - val codeVerifierBytes = ByteArray(96) // base64 has 6bit per char; (8/6)*96 = 128 - secureRandom.nextBytes(codeVerifierBytes) + val codeVerifierBytes = CryptographyRandom.nextBytes(96) // base64 has 6bit per char; (8/6)*96 = 128 return base64Encode(codeVerifierBytes).trimEnd('=') .replace("+", "-").replace("/", "_").replace("\n", "") } From ad4c9dced96c24bc5005d4cb2e650bacdcbf03cd Mon Sep 17 00:00:00 2001 From: Luna712 <142361265+Luna712@users.noreply.github.com> Date: Mon, 29 Jun 2026 14:27:48 -0600 Subject: [PATCH 04/12] Fix --- .../main/java/com/lagradost/cloudstream3/plugins/VotingApi.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/lagradost/cloudstream3/plugins/VotingApi.kt b/app/src/main/java/com/lagradost/cloudstream3/plugins/VotingApi.kt index 83248f970a3..3d8f24946d3 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/plugins/VotingApi.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/plugins/VotingApi.kt @@ -26,7 +26,7 @@ object VotingApi { .fold("") { str, it -> str + "%02x".format(it) } suspend fun SitePlugin.getVotes(): Int = getVotes(url) - fun SitePlugin.hasVoted(): Boolean = hasVoted(url) + suspend fun SitePlugin.hasVoted(): Boolean = hasVoted(url) suspend fun SitePlugin.vote(): Int = vote(url) fun SitePlugin.canVote(): Boolean = canVote(this.url) @@ -52,7 +52,7 @@ object VotingApi { votesCache[pluginUrl] = it } - fun hasVoted(pluginUrl: String) = + suspend fun hasVoted(pluginUrl: String) = getKey("cs3-votes/${transformUrl(pluginUrl)}") ?: false fun canVote(pluginUrl: String): Boolean = From fd346a9b722f95b272f38b7bc74b17790cf64e82 Mon Sep 17 00:00:00 2001 From: Luna712 <142361265+Luna712@users.noreply.github.com> Date: Mon, 29 Jun 2026 14:28:53 -0600 Subject: [PATCH 05/12] Update --- .../ui/settings/extensions/PluginDetailsFragment.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/settings/extensions/PluginDetailsFragment.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/settings/extensions/PluginDetailsFragment.kt index 0dcbece6cc3..f6aa8fbafbc 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/settings/extensions/PluginDetailsFragment.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/settings/extensions/PluginDetailsFragment.kt @@ -134,7 +134,7 @@ class PluginDetailsFragment(val data: PluginViewData) : BaseBottomSheetDialogFra } } - private fun updateVoting(value: Int) { + private suspend fun updateVoting(value: Int) { val metadata = data.plugin.second binding?.apply { pluginVotes.text = value.toString() @@ -149,4 +149,4 @@ class PluginDetailsFragment(val data: PluginViewData) : BaseBottomSheetDialogFra } } } -} \ No newline at end of file +} From c2ac94cb071cceb10b43b54588f4991bc9f59cd3 Mon Sep 17 00:00:00 2001 From: Luna712 <142361265+Luna712@users.noreply.github.com> Date: Mon, 29 Jun 2026 16:01:35 -0600 Subject: [PATCH 06/12] Update --- .../cloudstream3/utils/videoskip/AnimeSkip.kt | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/com/lagradost/cloudstream3/utils/videoskip/AnimeSkip.kt b/app/src/main/java/com/lagradost/cloudstream3/utils/videoskip/AnimeSkip.kt index df9d56217fd..35c2a5ed72e 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/utils/videoskip/AnimeSkip.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/utils/videoskip/AnimeSkip.kt @@ -17,11 +17,12 @@ import com.lagradost.cloudstream3.syncproviders.PlainAuthRepo import com.lagradost.cloudstream3.ui.result.ResultEpisode import com.lagradost.cloudstream3.utils.AppUtils.parseJson import com.lagradost.cloudstream3.utils.AppUtils.toJson +import dev.whyoleg.cryptography.CryptographyProvider +import dev.whyoleg.cryptography.algorithms.MD5 import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable import java.math.BigInteger import java.util.concurrent.ConcurrentHashMap -import java.security.MessageDigest class AnimeSkipAuth : AuthAPI() { override val name = "AnimeSkip" @@ -31,9 +32,11 @@ class AnimeSkipAuth : AuthAPI() { override val hasInApp = true override val createAccountUrl = "https://anime-skip.com/account" val baseClientId = "as1JgiMbW4wKfmTLWXS79iTDQFll76pk" - fun md5(input: String): String { - val md = MessageDigest.getInstance("MD5") - return BigInteger(1, md.digest(input.toByteArray())).toString(16).padStart(32, '0') + + suspend fun md5(input: String): String { + val digest = CryptographyProvider.Default.get(MD5) + .hasher().hash(input.encodeToByteArray()) + return BigInteger(1, digest).toString(16).padStart(32, '0') } @Serializable From 1af957309e5e46eb3809e32597bf5d730543a554 Mon Sep 17 00:00:00 2001 From: Luna712 <142361265+Luna712@users.noreply.github.com> Date: Mon, 29 Jun 2026 16:07:10 -0600 Subject: [PATCH 07/12] Update --- .../cloudstream3/plugins/RepositoryManager.kt | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/com/lagradost/cloudstream3/plugins/RepositoryManager.kt b/app/src/main/java/com/lagradost/cloudstream3/plugins/RepositoryManager.kt index c83c694f71d..43a6a68d2bd 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/plugins/RepositoryManager.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/plugins/RepositoryManager.kt @@ -16,6 +16,8 @@ import com.lagradost.cloudstream3.plugins.PluginManager.getPluginSanitizedFileNa import com.lagradost.cloudstream3.plugins.PluginManager.unloadPlugin import com.lagradost.cloudstream3.ui.settings.extensions.REPOSITORIES_KEY import com.lagradost.cloudstream3.ui.settings.extensions.RepositoryData +import dev.whyoleg.cryptography.CryptographyProvider +import dev.whyoleg.cryptography.algorithms.SHA256 import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock import kotlinx.serialization.SerialName @@ -24,7 +26,6 @@ import java.io.File import java.nio.file.AtomicMoveNotSupportedException import java.nio.file.Files import java.nio.file.StandardCopyOption -import java.security.MessageDigest import java.util.concurrent.TimeUnit /** @@ -87,18 +88,18 @@ object RepositoryManager { /** Returns a SHA-256 string of the file content. * Example: "sha256-b70462c264cb7f90fc2860a8e58d7544ce747ff347d1d11fa093623901853573" **/ @WorkerThread - fun sha256(file: File): String { - val digest = MessageDigest.getInstance("SHA-256") - + suspend fun sha256(file: File): String { + val hasher = CryptographyProvider.Default.get(SHA256).hasher() file.inputStream().use { fis -> val buffer = ByteArray(8192) var read = fis.read(buffer) while (read != -1) { - digest.update(buffer, 0, read) + hasher.update(buffer, 0, read) read = fis.read(buffer) } } - return "sha256-" + digest.digest().joinToString("") { "%02x".format(it) } + + return "sha256-" + hasher.hash().joinToString("") { "%02x".format(it) } } /* Convert raw.githubusercontent.com urls to cdn.jsdelivr.net if enabled in settings */ From 2f00d7c8bd5a7dc37cade820e2a1ff7124dc68f8 Mon Sep 17 00:00:00 2001 From: Luna712 <142361265+Luna712@users.noreply.github.com> Date: Mon, 29 Jun 2026 16:11:53 -0600 Subject: [PATCH 08/12] Update --- .../cloudstream3/syncproviders/providers/SimklApi.kt | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/com/lagradost/cloudstream3/syncproviders/providers/SimklApi.kt b/app/src/main/java/com/lagradost/cloudstream3/syncproviders/providers/SimklApi.kt index 075c08bb81d..5a3fa623dd8 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/syncproviders/providers/SimklApi.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/syncproviders/providers/SimklApi.kt @@ -33,8 +33,8 @@ import com.lagradost.cloudstream3.utils.AppUtils.toJson import com.lagradost.cloudstream3.utils.AppUtils.tryParseJson import com.lagradost.cloudstream3.utils.DataStoreHelper.toYear import com.lagradost.cloudstream3.utils.txt +import dev.whyoleg.cryptography.random.CryptographyRandom import java.math.BigInteger -import java.security.SecureRandom import java.text.SimpleDateFormat import java.time.Instant import java.util.Date @@ -917,13 +917,11 @@ class SimklApi : SyncAPI() { } override fun loginRequest(): AuthLoginPage? { - val lastLoginState = BigInteger(130, SecureRandom()).toString(32) - val url = - "https://simkl.com/oauth/authorize?response_type=code&client_id=$CLIENT_ID&redirect_uri=$APP_STRING://${redirectUrlIdentifier}&state=$lastLoginState" - + val lastLoginState = BigInteger(130, CryptographyRandom.nextBytes(17)).toString(32) + val url = "https://simkl.com/oauth/authorize?response_type=code&client_id=$CLIENT_ID&redirect_uri=$APP_STRING://$redirectUrlIdentifier&state=$lastLoginState" return AuthLoginPage( url = url, - payload = lastLoginState + payload = lastLoginState, ) } From a1ff328c2327d7ae191d404b5072f4cb3fe055bb Mon Sep 17 00:00:00 2001 From: Luna712 <142361265+Luna712@users.noreply.github.com> Date: Mon, 29 Jun 2026 16:14:56 -0600 Subject: [PATCH 09/12] Update --- .../java/com/lagradost/cloudstream3/ui/player/CS3IPlayer.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/player/CS3IPlayer.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/player/CS3IPlayer.kt index d7e10c81441..ff652441cfa 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/player/CS3IPlayer.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/player/CS3IPlayer.kt @@ -112,7 +112,6 @@ import kotlinx.coroutines.delay import okhttp3.Interceptor import org.chromium.net.CronetEngine import java.io.File -import java.security.SecureRandom import java.util.UUID import java.util.concurrent.Executors import javax.net.ssl.HttpsURLConnection @@ -1893,7 +1892,7 @@ class CS3IPlayer : IPlayer { if (ignoreSSL) { // Disables ssl check val sslContext: SSLContext = SSLContext.getInstance("TLS") - sslContext.init(null, arrayOf(SSLTrustManager()), SecureRandom()) + sslContext.init(null, arrayOf(SSLTrustManager()), null) sslContext.createSSLEngine() HttpsURLConnection.setDefaultHostnameVerifier { _: String, _: SSLSession -> true From 6f32763a100b316ab435e109249dbf96b9f4ae66 Mon Sep 17 00:00:00 2001 From: Luna712 <142361265+Luna712@users.noreply.github.com> Date: Mon, 29 Jun 2026 16:23:10 -0600 Subject: [PATCH 10/12] Update --- .../cloudstream3/plugins/RepositoryManager.kt | 24 ++++++++++--------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/com/lagradost/cloudstream3/plugins/RepositoryManager.kt b/app/src/main/java/com/lagradost/cloudstream3/plugins/RepositoryManager.kt index 43a6a68d2bd..0787153962e 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/plugins/RepositoryManager.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/plugins/RepositoryManager.kt @@ -84,22 +84,24 @@ object RepositoryManager { private val GH_REGEX = Regex("^https://raw.githubusercontent.com/([A-Za-z0-9-]+)/([A-Za-z0-9_.-]+)/(.*)$") - /** Returns a SHA-256 string of the file content. * Example: "sha256-b70462c264cb7f90fc2860a8e58d7544ce747ff347d1d11fa093623901853573" **/ @WorkerThread - suspend fun sha256(file: File): String { - val hasher = CryptographyProvider.Default.get(SHA256).hasher() - file.inputStream().use { fis -> - val buffer = ByteArray(8192) - var read = fis.read(buffer) - while (read != -1) { - hasher.update(buffer, 0, read) - read = fis.read(buffer) + fun sha256(file: File): String { + val hashFunction = CryptographyProvider.Default.get(SHA256) + .hasher().createHashFunction() + hashFunction.use { + file.inputStream().use { fis -> + val buffer = ByteArray(8192) + var read = fis.read(buffer) + while (read != -1) { + it.update(buffer, 0, read) + read = fis.read(buffer) + } } - } - return "sha256-" + hasher.hash().joinToString("") { "%02x".format(it) } + return "sha256-" + it.hashToByteArray().joinToString("") { b -> "%02x".format(b) } + } } /* Convert raw.githubusercontent.com urls to cdn.jsdelivr.net if enabled in settings */ From fd4a042186545a5ca6ee37e9fa01599c21d86e28 Mon Sep 17 00:00:00 2001 From: Luna712 <142361265+Luna712@users.noreply.github.com> Date: Mon, 29 Jun 2026 16:31:35 -0600 Subject: [PATCH 11/12] Fix --- .../com/lagradost/cloudstream3/utils/videoskip/AnimeSkip.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/java/com/lagradost/cloudstream3/utils/videoskip/AnimeSkip.kt b/app/src/main/java/com/lagradost/cloudstream3/utils/videoskip/AnimeSkip.kt index 35c2a5ed72e..d55a430b218 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/utils/videoskip/AnimeSkip.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/utils/videoskip/AnimeSkip.kt @@ -18,6 +18,7 @@ import com.lagradost.cloudstream3.ui.result.ResultEpisode import com.lagradost.cloudstream3.utils.AppUtils.parseJson import com.lagradost.cloudstream3.utils.AppUtils.toJson import dev.whyoleg.cryptography.CryptographyProvider +import dev.whyoleg.cryptography.DelicateCryptographyApi import dev.whyoleg.cryptography.algorithms.MD5 import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @@ -34,6 +35,7 @@ class AnimeSkipAuth : AuthAPI() { val baseClientId = "as1JgiMbW4wKfmTLWXS79iTDQFll76pk" suspend fun md5(input: String): String { + @OptIn(DelicateCryptographyApi::class) val digest = CryptographyProvider.Default.get(MD5) .hasher().hash(input.encodeToByteArray()) return BigInteger(1, digest).toString(16).padStart(32, '0') From 40e857bf9eaade48d27763d0ef58294c0aeeace3 Mon Sep 17 00:00:00 2001 From: Luna712 <142361265+Luna712@users.noreply.github.com> Date: Mon, 29 Jun 2026 16:42:05 -0600 Subject: [PATCH 12/12] Update --- .../lagradost/cloudstream3/plugins/RepositoryManager.kt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/src/main/java/com/lagradost/cloudstream3/plugins/RepositoryManager.kt b/app/src/main/java/com/lagradost/cloudstream3/plugins/RepositoryManager.kt index 0787153962e..18173d1cb70 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/plugins/RepositoryManager.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/plugins/RepositoryManager.kt @@ -90,6 +90,13 @@ object RepositoryManager { fun sha256(file: File): String { val hashFunction = CryptographyProvider.Default.get(SHA256) .hasher().createHashFunction() + // Use kotlinx-io eventually + /* + return hashFunction.use { + it.update(file.asSource()) + "sha256-" + it.hashToByteArray().joinToString("") { b -> "%02x".format(b) } + } + */ hashFunction.use { file.inputStream().use { fis -> val buffer = ByteArray(8192)