Merge pull request #1914 from Xwite/master

feat(EncoderUtils): support zeropadding
pull/1915/head
kunfei 3 years ago committed by GitHub
commit 056f9accb1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 13
      app/src/main/assets/help/jsHelp.md
  2. 10
      app/src/main/java/io/legado/app/help/JsExtensions.kt
  3. 5
      app/src/main/java/io/legado/app/ui/book/remote/RemoteBookAdapter.kt
  4. 62
      app/src/main/java/io/legado/app/utils/DigestUtils.kt
  5. 16
      app/src/main/java/io/legado/app/utils/EncoderUtils.kt
  6. 3
      app/src/main/java/io/legado/app/utils/MD5Utils.kt

@ -57,7 +57,9 @@ java.ajaxAll(urlList: Array<String>): Array<StrResponse?>
java.connect(urlStr): StrResponse java.connect(urlStr): StrResponse
java.post(url: String, body: String, headerMap: Map<String, String>): Connection.Response java.post(url: String, body: String, headerMap: Map<String, String>): Connection.Response
java.get(url: String, headerMap: Map<String, String>): Connection.Response java.get(url: String, headerMap: Map<String, String>): Connection.Response
java.head(url: String, headerMap: Map<String, String>): Connection.Response java.head(url: String, headerMap: Map<String, String>): Connection.Response
* 使用webView访问网络 * 使用webView访问网络
@ -132,8 +134,13 @@ deleteFile(path: String)
``` ```
**** ****
> [常见加密解密算法介绍](https://www.yijiyong.com/algorithm/encryption/01-intro.html) > [常见加密解密算法介绍](https://www.yijiyong.com/algorithm/encryption/01-intro.html)
> [相关概念](https://blog.csdn.net/OrangeJack/article/details/82913804) > [相关概念](https://blog.csdn.net/OrangeJack/article/details/82913804)
> [Android支持的transformation](https://developer.android.google.cn/reference/kotlin/javax/crypto/Cipher?hl=en) > [Android支持的transformation](https://developer.android.google.cn/reference/kotlin/javax/crypto/Cipher?hl=en)
> 其他加密方式 可在js中[调用](https://m.jb51.net/article/92138.htm)[hutool-crypto](https://www.hutool.cn/docs/#/)
* AES * AES
> transformation默认实现AES/ECB/PKCS5Padding > transformation默认实现AES/ECB/PKCS5Padding
``` ```
@ -164,14 +171,14 @@ java.tripleDESEncodeBase64Str(data: String,key: String,mode: String,padding: Str
java.tripleDESDecodeStr(data: String,key: String,mode: String,padding: String,iv: String): String? java.tripleDESDecodeStr(data: String,key: String,mode: String,padding: String,iv: String): String?
``` ```
* 摘要 * 摘要
> algorithm支持MD5 SHA-1 SHA-224 SHA-256 SHA-384 SHA-512 > MD5 SHA-1 SHA-224 SHA-256 SHA-384 SHA-512
``` ```
java.digestHex(data: String, algorithm: String,): String? java.digestHex(data: String, algorithm: String,): String?
java.digestBase64Str(data: String, algorithm: String,): String? java.digestBase64Str(data: String, algorithm: String,): String?
``` ```
* HMac(散列消息鉴别码) * HMac(部分算法暂不支持)
> algorithm支持DESMAC DESMAC/CFB8 DESedeMAC DESedeMAC/CFB8 DESedeMAC64 DESwithISO9797 HmacMD5 HmacSHA* ISO9797ALG3MAC PBEwithSHA* > DESMAC DESMAC/CFB8 DESedeMAC DESedeMAC/CFB8 DESedeMAC64 DESwithISO9797 HmacMD5 HmacSHA* ISO9797ALG3MAC PBEwithSHA*
``` ```
java.HMacHex(data: String, algorithm: String, key: String): String java.HMacHex(data: String, algorithm: String, key: String): String

@ -3,6 +3,8 @@ package io.legado.app.help
import android.net.Uri import android.net.Uri
import android.util.Base64 import android.util.Base64
import androidx.annotation.Keep import androidx.annotation.Keep
import cn.hutool.crypto.digest.DigestUtil
import cn.hutool.crypto.digest.HMac
import io.legado.app.constant.AppConst import io.legado.app.constant.AppConst
import io.legado.app.constant.AppConst.dateFormat import io.legado.app.constant.AppConst.dateFormat
import io.legado.app.constant.AppLog import io.legado.app.constant.AppLog
@ -960,7 +962,7 @@ interface JsExtensions {
data: String, data: String,
algorithm: String, algorithm: String,
): String { ): String {
return DigestUtils.getDigest(algorithm, data) return DigestUtil.digester(algorithm).digestHex(data)
} }
/** /**
@ -974,7 +976,7 @@ interface JsExtensions {
data: String, data: String,
algorithm: String, algorithm: String,
): String { ): String {
return Base64.encodeToString(DigestUtils.getDigest(algorithm, data.toByteArray()), Base64.NO_WRAP) return Base64.encodeToString(DigestUtil.digester(algorithm).digest(data), Base64.NO_WRAP)
} }
/** /**
@ -990,7 +992,7 @@ interface JsExtensions {
algorithm: String, algorithm: String,
key: String key: String
): String { ): String {
return DigestUtils.getHMac(algorithm, key, data) return HMac(algorithm, key.toByteArray()).digestHex(data)
} }
/** /**
@ -1006,7 +1008,7 @@ interface JsExtensions {
algorithm: String, algorithm: String,
key: String key: String
): String { ): String {
return Base64.encodeToString(DigestUtils.getHMac(algorithm, key.toByteArray(), data.toByteArray()), Base64.NO_WRAP) return Base64.encodeToString(HMac(algorithm, key.toByteArray()).digest(data), Base64.NO_WRAP)
} }
fun md5Encode(str: String): String { fun md5Encode(str: String): String {

@ -2,12 +2,11 @@ package io.legado.app.ui.book.remote
import android.content.Context import android.content.Context
import android.view.ViewGroup import android.view.ViewGroup
import cn.hutool.core.date.LocalDateTimeUtil
import io.legado.app.base.adapter.ItemViewHolder import io.legado.app.base.adapter.ItemViewHolder
import io.legado.app.base.adapter.RecyclerAdapter import io.legado.app.base.adapter.RecyclerAdapter
import io.legado.app.databinding.ItemRemoteBookBinding import io.legado.app.databinding.ItemRemoteBookBinding
import io.legado.app.utils.ConvertUtils import io.legado.app.utils.ConvertUtils
import java.text.SimpleDateFormat
import java.util.Date
/** /**
@ -39,7 +38,7 @@ class RemoteBookAdapter (context: Context, val callBack: CallBack) :
tvName.text = item.filename.substringBeforeLast(".") tvName.text = item.filename.substringBeforeLast(".")
tvContentType.text = item.contentType tvContentType.text = item.contentType
tvSize.text = ConvertUtils.formatFileSize(item.size) tvSize.text = ConvertUtils.formatFileSize(item.size)
tvDate.text = SimpleDateFormat("yyyy-MM-dd").format(Date(item.lastModify)) tvDate.text = LocalDateTimeUtil.format(LocalDateTimeUtil.of(item.lastModify), "yyyy-MM-dd")
} }
} }

@ -1,62 +0,0 @@
package io.legado.app.utils
import java.security.MessageDigest
import javax.crypto.Mac
import javax.crypto.spec.SecretKeySpec
object DigestUtils {
/**
* 消息摘要
* 支持MD5 SHA-1 SHA-224 SHA-256 SHA-384 SHA-512
* https://developer.android.google.cn/reference/java/security/MessageDigest?hl=en
*/
fun getDigest(
algorithm: String,
data: String?
): String {
data ?: return ""
val bytes = getDigest(algorithm, data.toByteArray())
return StringUtils.byteToHexString(bytes)
}
fun getDigest(
algorithm: String,
data: ByteArray
): ByteArray {
return kotlin.runCatching {
val messageDigest = MessageDigest.getInstance(algorithm)
messageDigest.digest(data)
}.getOrThrow()
}
/**
* 散列消息鉴别码
* 支持DESMAC DESMAC/CFB8 DESedeMAC DESedeMAC/CFB8 DESedeMAC64 DESwithISO9797 HmacMD5 HmacSHA* ISO9797ALG3MAC PBEwithSHA*
* https://developer.android.google.cn/reference/kotlin/javax/crypto/Mac?hl=en
*/
fun getHMac(
algorithm: String,
key: String,
data: String?
): String {
data ?: return ""
val bytes = getHMac(algorithm, key.toByteArray(), data.toByteArray())
return StringUtils.byteToHexString(bytes)
}
fun getHMac(
algorithm: String,
key: ByteArray,
data: ByteArray
): ByteArray {
return kotlin.runCatching {
val mac= Mac.getInstance(algorithm)
val keySpec = SecretKeySpec(key, algorithm)
mac.init(keySpec)
mac.update(data)
mac.doFinal()
}.getOrThrow()
}
}

@ -2,9 +2,9 @@ package io.legado.app.utils
import android.util.Base64 import android.util.Base64
import java.security.spec.AlgorithmParameterSpec import java.security.spec.AlgorithmParameterSpec
import javax.crypto.Cipher
import javax.crypto.spec.IvParameterSpec import javax.crypto.spec.IvParameterSpec
import javax.crypto.spec.SecretKeySpec import javax.crypto.spec.SecretKeySpec
import cn.hutool.crypto.symmetric.SymmetricCrypto
/** /**
* transformations https://developer.android.google.cn/reference/kotlin/javax/crypto/Cipher?hl=en * transformations https://developer.android.google.cn/reference/kotlin/javax/crypto/Cipher?hl=en
@ -328,16 +328,14 @@ object EncoderUtils {
): ByteArray? { ): ByteArray? {
return if (data == null || data.isEmpty() || key == null || key.isEmpty()) null return if (data == null || data.isEmpty() || key == null || key.isEmpty()) null
else { else {
//hutool support zeropadding
val keySpec = SecretKeySpec(key, algorithm) val keySpec = SecretKeySpec(key, algorithm)
val cipher = Cipher.getInstance(transformation) var params: AlgorithmParameterSpec? = null
val mode = if (isEncrypt) Cipher.ENCRYPT_MODE else Cipher.DECRYPT_MODE if (iv != null && !iv.isEmpty()) {
if (iv == null || iv.isEmpty()) { params = IvParameterSpec(iv)
cipher.init(mode, keySpec)
} else {
val params: AlgorithmParameterSpec = IvParameterSpec(iv)
cipher.init(mode, keySpec, params)
} }
cipher.doFinal(data) val symmetricCrypto = SymmetricCrypto(transformation, keySpec, params)
if (isEncrypt) symmetricCrypto.encrypt(data) else symmetricCrypto.decrypt(data)
} }
} }

@ -1,5 +1,6 @@
package io.legado.app.utils package io.legado.app.utils
import cn.hutool.crypto.digest.DigestUtil
/** /**
* 将字符串转化为MD5 * 将字符串转化为MD5
*/ */
@ -7,7 +8,7 @@ package io.legado.app.utils
object MD5Utils { object MD5Utils {
fun md5Encode(str: String?): String { fun md5Encode(str: String?): String {
return DigestUtils.getDigest("MD5", str) return DigestUtil.digester("MD5").digestHex(str)
} }
fun md5Encode16(str: String): String { fun md5Encode16(str: String): String {

Loading…
Cancel
Save