Merge pull request #1902 from Xwite/master

实现aes/des/3des/digest/Hmac
pull/1905/head
kunfei 3 years ago committed by GitHub
commit ebc5e1b85a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      app/build.gradle
  2. 45
      app/src/main/assets/help/jsHelp.md
  3. 4
      app/src/main/assets/updateLog.md
  4. 212
      app/src/main/java/io/legado/app/help/JsExtensions.kt
  5. 5
      app/src/main/java/io/legado/app/ui/book/remote/RemoteBookAdapter.kt
  6. 62
      app/src/main/java/io/legado/app/utils/DigestUtils.kt
  7. 194
      app/src/main/java/io/legado/app/utils/EncoderUtils.kt
  8. 24
      app/src/main/java/io/legado/app/utils/MD5Utils.kt

@ -255,7 +255,7 @@ dependencies {
implementation('com.github.liuyueyi.quick-chinese-transfer:quick-transfer-core:0.2.3') implementation('com.github.liuyueyi.quick-chinese-transfer:quick-transfer-core:0.2.3')
// //
implementation('cn.hutool:hutool-crypto:5.8.1') //implementation('cn.hutool:hutool-crypto:5.8.1')
//renderscriptToolkit //renderscriptToolkit
implementation('com.github.android:renderscript-intrinsics-replacement-toolkit:b6363490c3') implementation('com.github.android:renderscript-intrinsics-replacement-toolkit:b6363490c3')

@ -54,7 +54,11 @@ java.put(key, value)
java.ajax(urlStr): String java.ajax(urlStr): String
java.ajaxAll(urlList: Array<String>): Array<StrResponse?> java.ajaxAll(urlList: Array<String>): Array<StrResponse?>
//返回Response 方法body() code() message() header() raw() toString() //返回Response 方法body() code() message() header() raw() toString()
java.connect(urlStr): Response<String> java.connect(urlStr): StrResponse
java.post(url: String, body: 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
* 使用webView访问网络 * 使用webView访问网络
* @param html 直接用webView载入的html, 如果html为空直接访问url * @param html 直接用webView载入的html, 如果html为空直接访问url
@ -128,13 +132,11 @@ 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)
* AES * AES
> transformation默认实现AES/ECB/PKCS5Padding
``` ```
* @param data 传入的原始数据
* @param key AES加密的key
* @param transformation AES加密的方式 例如AES/ECB/PKCS5Padding
* @param iv ECB模式的偏移向量
java.aesDecodeToString(str: String, key: String, transformation: String, iv: String) java.aesDecodeToString(str: String, key: String, transformation: String, iv: String)
java.aesBase64DecodeToString(str: String, key: String, transformation: String, iv: String) java.aesBase64DecodeToString(str: String, key: String, transformation: String, iv: String)
@ -143,24 +145,37 @@ java.aesEncodeToString(str: String, key: String, transformation: String, iv: Str
java.aesEncodeToBase64String(str: String, key: String, transformation: String, iv: String) java.aesEncodeToBase64String(str: String, key: String, transformation: String, iv: String)
``` ```
* DES
> transformation默认实现DES/ECB/PKCS5Padding
```
java.desDecodeToString(str: String, key: String, transformation: String, iv: String)
java.desBase64DecodeToString(str: String, key: String, transformation: String, iv: String)
java.desEncodeToString(str: String, key: String, transformation: String, iv: String)
java.desEncodeToBase64String(str: String, key: String, transformation: String, iv: String)
```
* 3DES * 3DES
> tansformation默认实现DESede/ECB/PKCS5Padding
``` ```
* @param data 被加密的字符串
* @param key 密钥
* @param mode 模式 ECB/CBC/CFB/OFB/CTR
* @param padding 补码方式 NoPadding/PKCS5Padding/
* @param iv 加盐
java.tripleDESEncodeBase64Str(data: String,key: String,mode: String,padding: String,iv: String): String? java.tripleDESEncodeBase64Str(data: String,key: String,mode: String,padding: String,iv: String): String?
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
```
java.digestHex(data: String, algorithm: String,): String?
java.digestBase64Str(data: String, algorithm: String,): String?
```
* HMac(散列消息鉴别码)
> algorithm支持DESMAC DESMAC/CFB8 DESedeMAC DESedeMAC/CFB8 DESedeMAC64 DESwithISO9797 HmacMD5 HmacSHA* ISO9797ALG3MAC PBEwithSHA*
``` ```
* @param data 被摘要数据 java.HMacHex(data: String, algorithm: String, key: String): String
* @param algorithm 签名算法 MD5/SHA1/SHA256/SHA512
java.digestHex(data: String,algorithm: String,): String?
java.digestBase64Str(data: String,algorithm: String,): String? java.HMacBase64(data: String, algorithm: String, key: String): String
``` ```
* md5 * md5
``` ```

@ -15,6 +15,8 @@
* 修复部分txt章节结尾乱码bug * 修复部分txt章节结尾乱码bug
* 优化翻页流畅度 * 优化翻页流畅度
* js添加des HMac
* 登录ui用户信息默认加密方式改变,需要重新登录
**2022/05/21** **2022/05/21**
@ -322,4 +324,4 @@ eval(String(java.cacheFile(url)))
**2022/01/01** **2022/01/01**
* 修复本地txt问题,不在拷贝到私有目录,可以正常打开 * 修复本地txt问题,不在拷贝到私有目录,可以正常打开
* 优化txt目录识别,取目录数量最多的规则 * 优化txt目录识别,取目录数量最多的规则

@ -3,9 +3,6 @@ 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.symmetric.AES
import cn.hutool.crypto.symmetric.DESede
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
@ -299,14 +296,6 @@ interface JsExtensions {
return EncoderUtils.base64Encode(str, flags) return EncoderUtils.base64Encode(str, flags)
} }
fun md5Encode(str: String): String {
return MD5Utils.md5Encode(str)
}
fun md5Encode16(str: String): String {
return MD5Utils.md5Encode16(str)
}
/** /**
* 格式化时间 * 格式化时间
*/ */
@ -602,6 +591,13 @@ interface JsExtensions {
return UUID.randomUUID().toString() return UUID.randomUUID().toString()
} }
fun androidId(): String {
return AppConst.androidId
}
//******************对称加密解密************************//
/////AES
/** /**
* AES 解码为 ByteArray * AES 解码为 ByteArray
* @param str 传入的AES加密的数据 * @param str 传入的AES加密的数据
@ -640,6 +636,31 @@ interface JsExtensions {
return aesDecodeToByteArray(str, key, transformation, iv)?.let { String(it) } return aesDecodeToByteArray(str, key, transformation, iv)?.let { String(it) }
} }
/**
* AES解码为String算法参数经过Base64加密
*
* @param data 加密的字符串
* @param key Base64后的密钥
* @param mode 模式
* @param padding 补码方式
* @param iv Base64后的加盐
* @return 解密后的字符串
*/
fun aesDecodeArgsBase64Str(
data: String,
key: String,
mode: String,
padding: String,
iv: String
): String? {
return EncoderUtils.decryptAES(
data.encodeToByteArray(),
Base64.decode(key, Base64.NO_WRAP),
"AES/${mode}/${padding}",
Base64.decode(iv, Base64.NO_WRAP)
)?.let { String(it) }
}
/** /**
* 已经base64的AES 解码为 ByteArray * 已经base64的AES 解码为 ByteArray
* @param str 传入的AES Base64加密的数据 * @param str 传入的AES Base64加密的数据
@ -753,35 +774,78 @@ interface JsExtensions {
return aesEncodeToBase64ByteArray(data, key, transformation, iv)?.let { String(it) } return aesEncodeToBase64ByteArray(data, key, transformation, iv)?.let { String(it) }
} }
fun androidId(): String {
return AppConst.androidId
}
/** /**
* AES解密算法参数经过Base64加密 * AES加密并转为Base64算法参数经过Base64加密
* *
* @param data 加密的字符串 * @param data 加密的字符串
* @param key Base64后的密钥 * @param key Base64后的密钥
* @param mode 模式 * @param mode 模式
* @param padding 补码方式 * @param padding 补码方式
* @param iv Base64后的加盐 * @param iv Base64后的加盐
* @return 解密后的字符串 * @return 加密后的Base64
*/ */
fun aesDecodeArgsBase64Str( fun aesEncodeArgsBase64Str(
data: String, data: String,
key: String, key: String,
mode: String, mode: String,
padding: String, padding: String,
iv: String iv: String
): String? { ): String? {
return AES( return EncoderUtils.encryptAES2Base64(
mode, data.encodeToByteArray(),
padding,
Base64.decode(key, Base64.NO_WRAP), Base64.decode(key, Base64.NO_WRAP),
"AES/${mode}/${padding}",
Base64.decode(iv, Base64.NO_WRAP) Base64.decode(iv, Base64.NO_WRAP)
).decryptStr(data) )?.let { String(it) }
}
/////DES
fun desDecodeToString(
data: String, key: String, transformation: String, iv: String
): String? {
return EncoderUtils.decryptDES(
data.encodeToByteArray(),
key.encodeToByteArray(),
transformation,
iv.encodeToByteArray()
)?.let { String(it) }
}
fun desBase64DecodeToString(
data: String, key: String, transformation: String, iv: String
): String? {
return EncoderUtils.decryptBase64DES(
data.encodeToByteArray(),
key.encodeToByteArray(),
transformation,
iv.encodeToByteArray()
)?.let { String(it) }
}
fun desEncodeToString(
data: String, key: String, transformation: String, iv: String
): String? {
return EncoderUtils.encryptDES(
data.encodeToByteArray(),
key.encodeToByteArray(),
transformation,
iv.encodeToByteArray()
)?.let { String(it) }
}
fun desEncodeToBase64String(
data: String, key: String, transformation: String, iv: String
): String? {
return EncoderUtils.encryptDES2Base64(
data.encodeToByteArray(),
key.encodeToByteArray(),
transformation,
iv.encodeToByteArray()
)?.let { String(it) }
} }
//////3DES
/** /**
* 3DES解密 * 3DES解密
* *
@ -799,7 +863,12 @@ interface JsExtensions {
padding: String, padding: String,
iv: String iv: String
): String? { ): String? {
return DESede(mode, padding, key.toByteArray(), iv.toByteArray()).decryptStr(data) return EncoderUtils.decryptDESede(
data.encodeToByteArray(),
key.encodeToByteArray(),
"DESede/${mode}/${padding}",
iv.encodeToByteArray()
)?.let { String(it) }
} }
/** /**
@ -819,38 +888,14 @@ interface JsExtensions {
padding: String, padding: String,
iv: String iv: String
): String? { ): String? {
return DESede( return EncoderUtils.decryptDESede(
mode, data.encodeToByteArray(),
padding,
Base64.decode(key, Base64.NO_WRAP), Base64.decode(key, Base64.NO_WRAP),
"DESede/${mode}/${padding}",
Base64.decode(iv, Base64.NO_WRAP) Base64.decode(iv, Base64.NO_WRAP)
).decryptStr(data) )?.let { String(it) }
} }
/**
* AES加密并转为Base64算法参数经过Base64加密
*
* @param data 被加密的字符串
* @param key Base64后的密钥
* @param mode 模式
* @param padding 补码方式
* @param iv Base64后的加盐
* @return 加密后的Base64
*/
fun aesEncodeArgsBase64Str(
data: String,
key: String,
mode: String,
padding: String,
iv: String
): String? {
return AES(
mode,
padding,
Base64.decode(key, Base64.NO_WRAP),
Base64.decode(iv, Base64.NO_WRAP)
).encryptBase64(data)
}
/** /**
* 3DES加密并转为Base64 * 3DES加密并转为Base64
@ -869,7 +914,12 @@ interface JsExtensions {
padding: String, padding: String,
iv: String iv: String
): String? { ): String? {
return DESede(mode, padding, key.toByteArray(), iv.toByteArray()).encryptBase64(data) return EncoderUtils.encryptDESede2Base64(
data.encodeToByteArray(),
key.encodeToByteArray(),
"DESede/${mode}/${padding}",
iv.encodeToByteArray()
)?.let { String(it) }
} }
/** /**
@ -889,14 +939,16 @@ interface JsExtensions {
padding: String, padding: String,
iv: String iv: String
): String? { ): String? {
return DESede( return EncoderUtils.encryptDESede2Base64(
mode, data.encodeToByteArray(),
padding,
Base64.decode(key, Base64.NO_WRAP), Base64.decode(key, Base64.NO_WRAP),
"DESede/${mode}/${padding}",
Base64.decode(iv, Base64.NO_WRAP) Base64.decode(iv, Base64.NO_WRAP)
).encryptBase64(data) )?.let { String(it) }
} }
//******************消息摘要/散列消息鉴别码************************//
/** /**
* 生成摘要并转为16进制字符串 * 生成摘要并转为16进制字符串
* *
@ -907,8 +959,8 @@ interface JsExtensions {
fun digestHex( fun digestHex(
data: String, data: String,
algorithm: String, algorithm: String,
): String? { ): String {
return DigestUtil.digester(algorithm).digestHex(data) return DigestUtils.getDigest(algorithm, data)
} }
/** /**
@ -921,8 +973,48 @@ interface JsExtensions {
fun digestBase64Str( fun digestBase64Str(
data: String, data: String,
algorithm: String, algorithm: String,
): String? { ): String {
return Base64.encodeToString(DigestUtil.digester(algorithm).digest(data), Base64.NO_WRAP) return Base64.encodeToString(DigestUtils.getDigest(algorithm, data.toByteArray()), Base64.NO_WRAP)
}
/**
* 生成散列消息鉴别码并转为16进制字符串
*
* @param data 被摘要数据
* @param algorithm 签名算法
* @param key 密钥
* @return 16进制字符串
*/
fun HMacHex(
data: String,
algorithm: String,
key: String
): String {
return DigestUtils.getHMac(algorithm, key, data)
}
/**
* 生成散列消息鉴别码并转为Base64字符串
*
* @param data 被摘要数据
* @param algorithm 签名算法
* @param key 密钥
* @return Base64字符串
*/
fun HMacBase64(
data: String,
algorithm: String,
key: String
): String {
return Base64.encodeToString(DigestUtils.getHMac(algorithm, key.toByteArray(), data.toByteArray()), Base64.NO_WRAP)
}
fun md5Encode(str: String): String {
return MD5Utils.md5Encode(str)
}
fun md5Encode16(str: String): String {
return MD5Utils.md5Encode16(str)
} }
} }

@ -2,11 +2,12 @@ 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
/** /**
@ -38,7 +39,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 = LocalDateTimeUtil.format(LocalDateTimeUtil.of(item.lastModify), "yyyy-MM-dd") tvDate.text = SimpleDateFormat("yyyy-MM-dd").format(Date(item.lastModify))
} }
} }

@ -0,0 +1,62 @@
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()
}
}

@ -6,6 +6,9 @@ import javax.crypto.Cipher
import javax.crypto.spec.IvParameterSpec import javax.crypto.spec.IvParameterSpec
import javax.crypto.spec.SecretKeySpec import javax.crypto.spec.SecretKeySpec
/**
* transformations https://developer.android.google.cn/reference/kotlin/javax/crypto/Cipher?hl=en
*/
@Suppress("unused") @Suppress("unused")
object EncoderUtils { object EncoderUtils {
@ -47,7 +50,7 @@ object EncoderUtils {
* @param data The data. * @param data The data.
* @param key The key. * @param key The key.
* @param transformation The name of the transformation, * @param transformation The name of the transformation,
* 加密算法/加密模式/填充类型, *DES/CBC/PKCS5Padding*. * 加密算法/加密模式/填充类型, *AES/CBC/PKCS5Padding*.
* @param iv The buffer with the IV. The contents of the * @param iv The buffer with the IV. The contents of the
* buffer are copied to protect against subsequent modification. * buffer are copied to protect against subsequent modification.
* @return the Base64-encode bytes of AES encryption * @return the Base64-encode bytes of AES encryption
@ -56,7 +59,7 @@ object EncoderUtils {
fun encryptAES2Base64( fun encryptAES2Base64(
data: ByteArray?, data: ByteArray?,
key: ByteArray?, key: ByteArray?,
transformation: String? = "DES/ECB/PKCS5Padding", transformation: String? = "AES/ECB/PKCS5Padding",
iv: ByteArray? = null iv: ByteArray? = null
): ByteArray? { ): ByteArray? {
return Base64.encode(encryptAES(data, key, transformation, iv), Base64.NO_WRAP) return Base64.encode(encryptAES(data, key, transformation, iv), Base64.NO_WRAP)
@ -68,7 +71,7 @@ object EncoderUtils {
* @param data The data. * @param data The data.
* @param key The key. * @param key The key.
* @param transformation The name of the transformation, * @param transformation The name of the transformation,
* 加密算法/加密模式/填充类型, *DES/CBC/PKCS5Padding*. * 加密算法/加密模式/填充类型, *AES/CBC/PKCS5Padding*.
* @param iv The buffer with the IV. The contents of the * @param iv The buffer with the IV. The contents of the
* buffer are copied to protect against subsequent modification. * buffer are copied to protect against subsequent modification.
* @return the bytes of AES encryption * @return the bytes of AES encryption
@ -77,7 +80,7 @@ object EncoderUtils {
fun encryptAES( fun encryptAES(
data: ByteArray?, data: ByteArray?,
key: ByteArray?, key: ByteArray?,
transformation: String? = "DES/ECB/PKCS5Padding", transformation: String? = "AES/ECB/PKCS5Padding",
iv: ByteArray? = null iv: ByteArray? = null
): ByteArray? { ): ByteArray? {
return symmetricTemplate(data, key, "AES", transformation!!, iv, true) return symmetricTemplate(data, key, "AES", transformation!!, iv, true)
@ -90,7 +93,7 @@ object EncoderUtils {
* @param data The data. * @param data The data.
* @param key The key. * @param key The key.
* @param transformation The name of the transformation, * @param transformation The name of the transformation,
* 加密算法/加密模式/填充类型, *DES/CBC/PKCS5Padding*. * 加密算法/加密模式/填充类型, *AES/CBC/PKCS5Padding*.
* @param iv The buffer with the IV. The contents of the * @param iv The buffer with the IV. The contents of the
* buffer are copied to protect against subsequent modification. * buffer are copied to protect against subsequent modification.
* @return the bytes of AES decryption for Base64-encode bytes * @return the bytes of AES decryption for Base64-encode bytes
@ -99,7 +102,7 @@ object EncoderUtils {
fun decryptBase64AES( fun decryptBase64AES(
data: ByteArray?, data: ByteArray?,
key: ByteArray?, key: ByteArray?,
transformation: String = "DES/ECB/PKCS5Padding", transformation: String = "AES/ECB/PKCS5Padding",
iv: ByteArray? = null iv: ByteArray? = null
): ByteArray? { ): ByteArray? {
return decryptAES(Base64.decode(data, Base64.NO_WRAP), key, transformation, iv) return decryptAES(Base64.decode(data, Base64.NO_WRAP), key, transformation, iv)
@ -111,7 +114,7 @@ object EncoderUtils {
* @param data The data. * @param data The data.
* @param key The key. * @param key The key.
* @param transformation The name of the transformation, * @param transformation The name of the transformation,
* 加密算法/加密模式/填充类型, *DES/CBC/PKCS5Padding*. * 加密算法/加密模式/填充类型, *AES/CBC/PKCS5Padding*.
* @param iv The buffer with the IV. The contents of the * @param iv The buffer with the IV. The contents of the
* buffer are copied to protect against subsequent modification. * buffer are copied to protect against subsequent modification.
* @return the bytes of AES decryption * @return the bytes of AES decryption
@ -120,12 +123,185 @@ object EncoderUtils {
fun decryptAES( fun decryptAES(
data: ByteArray?, data: ByteArray?,
key: ByteArray?, key: ByteArray?,
transformation: String = "DES/ECB/PKCS5Padding", transformation: String = "AES/ECB/PKCS5Padding",
iv: ByteArray? = null iv: ByteArray? = null
): ByteArray? { ): ByteArray? {
return symmetricTemplate(data, key, "AES", transformation, iv, false) return symmetricTemplate(data, key, "AES", transformation, iv, false)
} }
//////////DES Start
/**
* Return the Base64-encode bytes of DES encryption.
*
* @param data The data.
* @param key The key.
* @param transformation The name of the transformation,
* 加密算法/加密模式/填充类型, *DES/CBC/PKCS5Padding*.
* @param iv The buffer with the IV. The contents of the
* buffer are copied to protect against subsequent modification.
* @return the Base64-encode bytes of AES encryption
*/
@Throws(Exception::class)
fun encryptDES2Base64(
data: ByteArray?,
key: ByteArray?,
transformation: String? = "DES/ECB/PKCS5Padding",
iv: ByteArray? = null
): ByteArray? {
return Base64.encode(encryptDES(data, key, transformation, iv), Base64.NO_WRAP)
}
/**
* Return the bytes of DES encryption.
*
* @param data The data.
* @param key The key.
* @param transformation The name of the transformation,
* 加密算法/加密模式/填充类型, *DES/CBC/PKCS5Padding*.
* @param iv The buffer with the IV. The contents of the
* buffer are copied to protect against subsequent modification.
* @return the bytes of AES encryption
*/
@Throws(Exception::class)
fun encryptDES(
data: ByteArray?,
key: ByteArray?,
transformation: String? = "DES/ECB/PKCS5Padding",
iv: ByteArray? = null
): ByteArray? {
return symmetricTemplate(data, key, "DES", transformation!!, iv, true)
}
/**
* Return the bytes of DES decryption for Base64-encode bytes.
*
* @param data The data.
* @param key The key.
* @param transformation The name of the transformation,
* 加密算法/加密模式/填充类型, *DES/CBC/PKCS5Padding*.
* @param iv The buffer with the IV. The contents of the
* buffer are copied to protect against subsequent modification.
* @return the bytes of AES decryption for Base64-encode bytes
*/
@Throws(Exception::class)
fun decryptBase64DES(
data: ByteArray?,
key: ByteArray?,
transformation: String = "DES/ECB/PKCS5Padding",
iv: ByteArray? = null
): ByteArray? {
return decryptDES(Base64.decode(data, Base64.NO_WRAP), key, transformation, iv)
}
/**
* Return the bytes of DES decryption.
*
* @param data The data.
* @param key The key.
* @param transformation The name of the transformation,
* 加密算法/加密模式/填充类型, *DES/CBC/PKCS5Padding*.
* @param iv The buffer with the IV. The contents of the
* buffer are copied to protect against subsequent modification.
* @return the bytes of AES decryption
*/
@Throws(Exception::class)
fun decryptDES(
data: ByteArray?,
key: ByteArray?,
transformation: String = "DES/ECB/PKCS5Padding",
iv: ByteArray? = null
): ByteArray? {
return symmetricTemplate(data, key, "DES", transformation, iv, false)
}
//////////DESede Start
/**
* Return the Base64-encode bytes of DESede encryption.
*
* @param data The data.
* @param key The key.
* @param transformation The name of the transformation,
* 加密算法/加密模式/填充类型, *DESede/CBC/PKCS5Padding*.
* @param iv The buffer with the IV. The contents of the
* buffer are copied to protect against subsequent modification.
* @return the Base64-encode bytes of AES encryption
*/
@Throws(Exception::class)
fun encryptDESede2Base64(
data: ByteArray?,
key: ByteArray?,
transformation: String? = "DESede/ECB/PKCS5Padding",
iv: ByteArray? = null
): ByteArray? {
return Base64.encode(encryptDESede(data, key, transformation, iv), Base64.NO_WRAP)
}
/**
* Return the bytes of DESede encryption.
*
* @param data The data.
* @param key The key.
* @param transformation The name of the transformation,
* 加密算法/加密模式/填充类型, *DESede/CBC/PKCS5Padding*.
* @param iv The buffer with the IV. The contents of the
* buffer are copied to protect against subsequent modification.
* @return the bytes of AES encryption
*/
@Throws(Exception::class)
fun encryptDESede(
data: ByteArray?,
key: ByteArray?,
transformation: String? = "DESede/ECB/PKCS5Padding",
iv: ByteArray? = null
): ByteArray? {
return symmetricTemplate(data, key, "DESede", transformation!!, iv, true)
}
/**
* Return the bytes of DESede decryption for Base64-encode bytes.
*
* @param data The data.
* @param key The key.
* @param transformation The name of the transformation,
* 加密算法/加密模式/填充类型, *DESede/CBC/PKCS5Padding*.
* @param iv The buffer with the IV. The contents of the
* buffer are copied to protect against subsequent modification.
* @return the bytes of AES decryption for Base64-encode bytes
*/
@Throws(Exception::class)
fun decryptBase64DESede(
data: ByteArray?,
key: ByteArray?,
transformation: String = "DESede/ECB/PKCS5Padding",
iv: ByteArray? = null
): ByteArray? {
return decryptDESede(Base64.decode(data, Base64.NO_WRAP), key, transformation, iv)
}
/**
* Return the bytes of DESede decryption.
*
* @param data The data.
* @param key The key.
* @param transformation The name of the transformation,
* 加密算法/加密模式/填充类型, *DESede/CBC/PKCS5Padding*.
* @param iv The buffer with the IV. The contents of the
* buffer are copied to protect against subsequent modification.
* @return the bytes of AES decryption
*/
@Throws(Exception::class)
fun decryptDESede(
data: ByteArray?,
key: ByteArray?,
transformation: String = "DESede/ECB/PKCS5Padding",
iv: ByteArray? = null
): ByteArray? {
return symmetricTemplate(data, key, "DESede", transformation, iv, false)
}
/** /**
* Return the bytes of symmetric encryption or decryption. * Return the bytes of symmetric encryption or decryption.
@ -166,4 +342,4 @@ object EncoderUtils {
} }
} }

@ -1,9 +1,5 @@
package io.legado.app.utils package io.legado.app.utils
import java.security.MessageDigest
import java.security.NoSuchAlgorithmException
/** /**
* 将字符串转化为MD5 * 将字符串转化为MD5
*/ */
@ -11,25 +7,7 @@ import java.security.NoSuchAlgorithmException
object MD5Utils { object MD5Utils {
fun md5Encode(str: String?): String { fun md5Encode(str: String?): String {
if (str == null) return "" return DigestUtils.getDigest("MD5", str)
var reStr = ""
try {
val md5: MessageDigest = MessageDigest.getInstance("MD5")
val bytes: ByteArray = md5.digest(str.toByteArray())
val stringBuffer: StringBuilder = StringBuilder()
for (b in bytes) {
val bt: Int = b.toInt() and 0xff
if (bt < 16) {
stringBuffer.append(0)
}
stringBuffer.append(Integer.toHexString(bt))
}
reStr = stringBuffer.toString()
} catch (e: NoSuchAlgorithmException) {
e.printOnDebug()
}
return reStr
} }
fun md5Encode16(str: String): String { fun md5Encode16(str: String): String {

Loading…
Cancel
Save