changed encryption and decryption utils
This commit is contained in:
parent
140cfa4794
commit
1d9344a26a
2 changed files with 17 additions and 45 deletions
|
@ -3,6 +3,7 @@ package eu.kanade.tachiyomi.animeextension.en.nineanime
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
|
import androidx.preference.EditTextPreference
|
||||||
import androidx.preference.ListPreference
|
import androidx.preference.ListPreference
|
||||||
import androidx.preference.MultiSelectListPreference
|
import androidx.preference.MultiSelectListPreference
|
||||||
import androidx.preference.PreferenceScreen
|
import androidx.preference.PreferenceScreen
|
||||||
|
@ -89,7 +90,7 @@ class Aniwave : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
||||||
override fun searchAnimeRequest(page: Int, query: String, filters: AnimeFilterList): Request {
|
override fun searchAnimeRequest(page: Int, query: String, filters: AnimeFilterList): Request {
|
||||||
val filters = AniwaveFilters.getSearchParameters(filters)
|
val filters = AniwaveFilters.getSearchParameters(filters)
|
||||||
|
|
||||||
val vrf = if (query.isNotBlank()) utils.vrfEncrypt(query) else ""
|
val vrf = if (query.isNotBlank()) utils.vrfEncrypt(getEncryptionKey(), query) else ""
|
||||||
var url = "$baseUrl/filter?keyword=$query"
|
var url = "$baseUrl/filter?keyword=$query"
|
||||||
|
|
||||||
if (filters.genre.isNotBlank()) url += filters.genre
|
if (filters.genre.isNotBlank()) url += filters.genre
|
||||||
|
@ -101,7 +102,7 @@ class Aniwave : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
||||||
if (filters.language.isNotBlank()) url += filters.language
|
if (filters.language.isNotBlank()) url += filters.language
|
||||||
if (filters.rating.isNotBlank()) url += filters.rating
|
if (filters.rating.isNotBlank()) url += filters.rating
|
||||||
|
|
||||||
return GET("$url&sort=${filters.sort}&page=$page&$vrf", refererHeaders)
|
return GET("$url&sort=${filters.sort}&page=$page&vrf=$vrf", refererHeaders)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun searchAnimeSelector(): String = popularAnimeSelector()
|
override fun searchAnimeSelector(): String = popularAnimeSelector()
|
||||||
|
@ -139,7 +140,7 @@ class Aniwave : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
||||||
override fun episodeListRequest(anime: SAnime): Request {
|
override fun episodeListRequest(anime: SAnime): Request {
|
||||||
val id = client.newCall(GET(baseUrl + anime.url)).execute().asJsoup()
|
val id = client.newCall(GET(baseUrl + anime.url)).execute().asJsoup()
|
||||||
.selectFirst("div[data-id]")!!.attr("data-id")
|
.selectFirst("div[data-id]")!!.attr("data-id")
|
||||||
val vrf = utils.vrfEncrypt(id)
|
val vrf = utils.vrfEncrypt(getEncryptionKey(), id)
|
||||||
|
|
||||||
val listHeaders = headers.newBuilder().apply {
|
val listHeaders = headers.newBuilder().apply {
|
||||||
add("Accept", "application/json, text/javascript, */*; q=0.01")
|
add("Accept", "application/json, text/javascript, */*; q=0.01")
|
||||||
|
@ -147,7 +148,7 @@ class Aniwave : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
||||||
add("X-Requested-With", "XMLHttpRequest")
|
add("X-Requested-With", "XMLHttpRequest")
|
||||||
}.build()
|
}.build()
|
||||||
|
|
||||||
return GET("$baseUrl/ajax/episode/list/$id?$vrf#${anime.url}", listHeaders)
|
return GET("$baseUrl/ajax/episode/list/$id?vrf=$vrf#${anime.url}", listHeaders)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun episodeListSelector() = "div.episodes ul > li > a"
|
override fun episodeListSelector() = "div.episodes ul > li > a"
|
||||||
|
@ -195,8 +196,8 @@ class Aniwave : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
||||||
|
|
||||||
override fun videoListRequest(episode: SEpisode): Request {
|
override fun videoListRequest(episode: SEpisode): Request {
|
||||||
val ids = episode.url.substringBefore("&")
|
val ids = episode.url.substringBefore("&")
|
||||||
val vrf = utils.vrfEncrypt(ids)
|
val vrf = utils.vrfEncrypt(getEncryptionKey(), ids)
|
||||||
val url = "/ajax/server/list/$ids?$vrf"
|
val url = "/ajax/server/list/$ids?vrf=$vrf"
|
||||||
val epurl = episode.url.substringAfter("epurl=")
|
val epurl = episode.url.substringAfter("epurl=")
|
||||||
|
|
||||||
val listHeaders = headers.newBuilder().apply {
|
val listHeaders = headers.newBuilder().apply {
|
||||||
|
@ -248,7 +249,7 @@ class Aniwave : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
||||||
private val mp4uploadExtractor by lazy { Mp4uploadExtractor(client) }
|
private val mp4uploadExtractor by lazy { Mp4uploadExtractor(client) }
|
||||||
|
|
||||||
private fun extractVideo(server: VideoData, epUrl: String): List<Video> {
|
private fun extractVideo(server: VideoData, epUrl: String): List<Video> {
|
||||||
val vrf = utils.vrfEncrypt(server.serverId)
|
val vrf = utils.vrfEncrypt(getEncryptionKey(), server.serverId)
|
||||||
|
|
||||||
val listHeaders = headers.newBuilder().apply {
|
val listHeaders = headers.newBuilder().apply {
|
||||||
add("Accept", "application/json, text/javascript, */*; q=0.01")
|
add("Accept", "application/json, text/javascript, */*; q=0.01")
|
||||||
|
@ -257,13 +258,13 @@ class Aniwave : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
||||||
}.build()
|
}.build()
|
||||||
|
|
||||||
val response = client.newCall(
|
val response = client.newCall(
|
||||||
GET("$baseUrl/ajax/server/${server.serverId}?$vrf", listHeaders),
|
GET("$baseUrl/ajax/server/${server.serverId}?vrf=$vrf", listHeaders),
|
||||||
).execute()
|
).execute()
|
||||||
if (response.code != 200) return emptyList()
|
if (response.code != 200) return emptyList()
|
||||||
|
|
||||||
return runCatching {
|
return runCatching {
|
||||||
val parsed = response.parseAs<ServerResponse>()
|
val parsed = response.parseAs<ServerResponse>()
|
||||||
val embedLink = utils.vrfDecrypt(parsed.result.url)
|
val embedLink = utils.vrfDecrypt(getDecryptionKey(), parsed.result.url)
|
||||||
when (server.serverName) {
|
when (server.serverName) {
|
||||||
"vidplay", "mycloud" -> {
|
"vidplay", "mycloud" -> {
|
||||||
val hosterName = when (server.serverName) {
|
val hosterName = when (server.serverName) {
|
||||||
|
|
|
@ -7,51 +7,22 @@ import javax.crypto.spec.SecretKeySpec
|
||||||
|
|
||||||
class AniwaveUtils {
|
class AniwaveUtils {
|
||||||
|
|
||||||
fun vrfEncrypt(input: String): String {
|
fun vrfEncrypt(key: String, input: String): String {
|
||||||
val rc4Key = SecretKeySpec("tGn6kIpVXBEUmqjD".toByteArray(), "RC4")
|
val rc4Key = SecretKeySpec(key.toByteArray(), "RC4")
|
||||||
val cipher = Cipher.getInstance("RC4")
|
val cipher = Cipher.getInstance("RC4")
|
||||||
cipher.init(Cipher.DECRYPT_MODE, rc4Key, cipher.parameters)
|
cipher.init(Cipher.DECRYPT_MODE, rc4Key, cipher.parameters)
|
||||||
|
|
||||||
var vrf = cipher.doFinal(input.toByteArray())
|
var vrf = cipher.doFinal(input.toByteArray())
|
||||||
vrf = Base64.encode(vrf, Base64.URL_SAFE or Base64.NO_WRAP)
|
vrf = Base64.encode(vrf, Base64.URL_SAFE or Base64.NO_WRAP)
|
||||||
vrf = Base64.encode(vrf, Base64.DEFAULT or Base64.NO_WRAP)
|
var vrfString = vrf.toString(Charsets.UTF_8)
|
||||||
vrf = vrfShift(vrf)
|
return java.net.URLEncoder.encode(vrfString, "utf-8")
|
||||||
vrf = vrf.reversed().toByteArray()
|
|
||||||
vrf = Base64.encode(vrf, Base64.URL_SAFE or Base64.NO_WRAP)
|
|
||||||
// vrf = rot13(vrf)
|
|
||||||
val stringVrf = vrf.toString(Charsets.UTF_8)
|
|
||||||
return "vrf=${java.net.URLEncoder.encode(stringVrf, "utf-8")}"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun vrfDecrypt(input: String): String {
|
fun vrfDecrypt(key: String, input: String): String {
|
||||||
var vrf = input.toByteArray()
|
var vrf = Base64.decode(input.toByteArray(), Base64.URL_SAFE)
|
||||||
vrf = Base64.decode(vrf, Base64.URL_SAFE)
|
val rc4Key = SecretKeySpec(key.toByteArray(), "RC4")
|
||||||
|
|
||||||
val rc4Key = SecretKeySpec("LUyDrL4qIxtIxOGs".toByteArray(), "RC4")
|
|
||||||
val cipher = Cipher.getInstance("RC4")
|
val cipher = Cipher.getInstance("RC4")
|
||||||
cipher.init(Cipher.DECRYPT_MODE, rc4Key, cipher.parameters)
|
cipher.init(Cipher.DECRYPT_MODE, rc4Key, cipher.parameters)
|
||||||
vrf = cipher.doFinal(vrf)
|
vrf = cipher.doFinal(vrf)
|
||||||
|
|
||||||
return URLDecoder.decode(vrf.toString(Charsets.UTF_8), "utf-8")
|
return URLDecoder.decode(vrf.toString(Charsets.UTF_8), "utf-8")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun rot13(vrf: ByteArray): ByteArray {
|
|
||||||
for (i in vrf.indices) {
|
|
||||||
val byte = vrf[i]
|
|
||||||
if (byte in 'A'.code..'Z'.code) {
|
|
||||||
vrf[i] = ((byte - 'A'.code + 13) % 26 + 'A'.code).toByte()
|
|
||||||
} else if (byte in 'a'.code..'z'.code) {
|
|
||||||
vrf[i] = ((byte - 'a'.code + 13) % 26 + 'a'.code).toByte()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return vrf
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun vrfShift(vrf: ByteArray): ByteArray {
|
|
||||||
for (i in vrf.indices) {
|
|
||||||
val shift = arrayOf(-2, -4, -5, 6, 2, -3, 3, 6)[i % 8]
|
|
||||||
vrf[i] = vrf[i].plus(shift).toByte()
|
|
||||||
}
|
|
||||||
return vrf
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue