diff --git a/app/src/main/java/io/legado/app/help/JsExtensions.kt b/app/src/main/java/io/legado/app/help/JsExtensions.kt index 53feb4054..64d8d0893 100644 --- a/app/src/main/java/io/legado/app/help/JsExtensions.kt +++ b/app/src/main/java/io/legado/app/help/JsExtensions.kt @@ -338,4 +338,149 @@ interface JsExtensions { Debug.log(msg) return msg } + + /** + * AES 解码为 ByteArray + * @param str 传入的AES加密的数据 + * @param key AES 解密的key + * @param transformation AES加密的方式 + * @param iv ECB模式的偏移向量 + */ + fun aesDecodeToByteArray( + str: String, + key: String, + transformation: String, + iv: String = "" + ): ByteArray? { + + return EncoderUtils.decryptAES( + data = str.encodeToByteArray(), + key = key.encodeToByteArray(), + transformation, + iv.encodeToByteArray() + ) + } + + /** + * AES 解码为 String + * @param str 传入的AES加密的数据 + * @param key AES 解密的key + * @param transformation AES加密的方式 + * @param iv ECB模式的偏移向量 + */ + + fun aesDecodeToString( + str: String, + key: String, + transformation: String, + iv: String = "" + ): String? { + return aesDecodeToByteArray(str, key, transformation, iv)?.let { String(it) } + } + + /** + * 已经base64的AES 解码为 ByteArray + * @param str 传入的AES Base64加密的数据 + * @param key AES 解密的key + * @param transformation AES加密的方式 + * @param iv ECB模式的偏移向量 + */ + + fun aesBase64DecodeToByteArray( + str: String, + key: String, + transformation: String, + iv: String = "" + ): ByteArray? { + return EncoderUtils.decryptBase64AES( + data = str.encodeToByteArray(), + key = key.encodeToByteArray(), + transformation, + iv.encodeToByteArray() + ) + } + + /** + * 已经base64的AES 解码为 String + * @param str 传入的AES Base64加密的数据 + * @param key AES 解密的key + * @param transformation AES加密的方式 + * @param iv ECB模式的偏移向量 + */ + + fun aesBase64DecodeToString( + str: String, + key: String, + transformation: String, + iv: String = "" + ): String? { + return aesBase64DecodeToByteArray(str, key, transformation, iv)?.let { String(it) } + } + + /** + * 加密aes为ByteArray + * @param data 传入的原始数据 + * @param key AES加密的key + * @param transformation AES加密的方式 + * @param iv ECB模式的偏移向量 + */ + fun aesEncodeToByteArray( + data: String, key: String, transformation: String, + iv: String = "" + ): ByteArray? { + return EncoderUtils.encryptAES( + data.encodeToByteArray(), + key = key.encodeToByteArray(), + transformation, + iv.encodeToByteArray() + ) + } + + /** + * 加密aes为String + * @param data 传入的原始数据 + * @param key AES加密的key + * @param transformation AES加密的方式 + * @param iv ECB模式的偏移向量 + */ + fun aesEncodeToString( + data: String, key: String, transformation: String, + iv: String = "" + ): String? { + return aesEncodeToByteArray(data, key, transformation, iv)?.let { String(it) } + } + + /** + * 加密aes后Base64化的ByteArray + * @param data 传入的原始数据 + * @param key AES加密的key + * @param transformation AES加密的方式 + * @param iv ECB模式的偏移向量 + */ + fun aesEncodeToBase64ByteArray( + data: String, key: String, transformation: String, + iv: String = "" + ): ByteArray? { + return EncoderUtils.encryptAES2Base64( + data.encodeToByteArray(), + key = key.encodeToByteArray(), + transformation, + iv.encodeToByteArray() + ) + } + + /** + * 加密aes后Base64化的String + * @param data 传入的原始数据 + * @param key AES加密的key + * @param transformation AES加密的方式 + * @param iv ECB模式的偏移向量 + */ + fun aesEncodeToBase64String( + data: String, key: String, transformation: String, + iv: String = "" + ): String? { + return aesEncodeToBase64ByteArray(data, key, transformation, iv)?.let { String(it) } + } + } diff --git a/app/src/main/java/io/legado/app/ui/book/cache/CacheViewModel.kt b/app/src/main/java/io/legado/app/ui/book/cache/CacheViewModel.kt index b40fb07cd..4554c094a 100644 --- a/app/src/main/java/io/legado/app/ui/book/cache/CacheViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/book/cache/CacheViewModel.kt @@ -207,7 +207,7 @@ class CacheViewModel(application: Application) : BaseViewModel(application) { //set css epubBook.resources.add( Resource( - "body,div{background:white;margin:0 auto;padding:0;outline:none;width:100%;}h2{color:#005a9c;text-align:left;}p{text-indent:2em;text-align:justify;}img{display:inline-block;width:100%;height:100%;max-width: 100%;max-height:100%;}".encodeToByteArray(), + "body,div{background:white;outline:none;width:100%;}h2{color:#005a9c;text-align:left;}p{text-indent:2em;text-align:justify;}img{display:inline-block;width:100%;height:auto;max-width: 100%;max-height:100%;}".encodeToByteArray(), "css/style.css" ) ) diff --git a/app/src/main/java/io/legado/app/utils/EncoderUtils.kt b/app/src/main/java/io/legado/app/utils/EncoderUtils.kt index 409cb802c..976f1c1be 100644 --- a/app/src/main/java/io/legado/app/utils/EncoderUtils.kt +++ b/app/src/main/java/io/legado/app/utils/EncoderUtils.kt @@ -1,6 +1,10 @@ package io.legado.app.utils import android.util.Base64 +import java.security.spec.AlgorithmParameterSpec +import javax.crypto.Cipher +import javax.crypto.spec.IvParameterSpec +import javax.crypto.spec.SecretKeySpec @Suppress("unused") object EncoderUtils { @@ -34,4 +38,124 @@ object EncoderUtils { fun base64Encode(str: String, flags: Int = Base64.NO_WRAP): String? { return Base64.encodeToString(str.toByteArray(), flags) } + //////////AES Start + + /** + * Return the Base64-encode bytes of AES encryption. + * + * @param data The data. + * @param key The key. + * @param transformation The name of the transformation, e.g., *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 + */ + fun encryptAES2Base64( + data: ByteArray?, + key: ByteArray?, + transformation: String?, + iv: ByteArray? + ): ByteArray? { + return Base64.encode(encryptAES(data, key, transformation, iv), Base64.NO_WRAP) + } + + /** + * Return the bytes of AES encryption. + * + * @param data The data. + * @param key The key. + * @param transformation The name of the transformation, e.g., *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 + */ + fun encryptAES( + data: ByteArray?, + key: ByteArray?, + transformation: String?, + iv: ByteArray? + ): ByteArray? { + return symmetricTemplate(data, key, "AES", transformation!!, iv, true) + } + + + /** + * Return the bytes of AES decryption for Base64-encode bytes. + * + * @param data The data. + * @param key The key. + * @param transformation The name of the transformation, e.g., *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 + */ + fun decryptBase64AES( + data: ByteArray?, + key: ByteArray?, + transformation: String?, + iv: ByteArray? + ): ByteArray? { + return decryptAES(Base64.decode(data, Base64.NO_WRAP), key, transformation, iv) + } + + /** + * Return the bytes of AES decryption. + * + * @param data The data. + * @param key The key. + * @param transformation The name of the transformation, e.g., *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 + */ + fun decryptAES( + data: ByteArray?, + key: ByteArray?, + transformation: String?, + iv: ByteArray? + ): ByteArray? { + return symmetricTemplate(data, key, "AES", transformation!!, iv, false) + } + + + /** + * Return the bytes of symmetric encryption or decryption. + * + * @param data The data. + * @param key The key. + * @param algorithm The name of algorithm. + * @param transformation The name of the transformation, e.g., DES/CBC/PKCS5Padding. + * @param isEncrypt True to encrypt, false otherwise. + * @return the bytes of symmetric encryption or decryption + */ + + private fun symmetricTemplate( + data: ByteArray?, + key: ByteArray?, + algorithm: String, + transformation: String, + iv: ByteArray?, + isEncrypt: Boolean + ): ByteArray? { + return if (data == null || data.isEmpty() || key == null || key.isEmpty()) null else try { + val keySpec = SecretKeySpec(key, algorithm) + val cipher = Cipher.getInstance(transformation) + if (iv == null || iv.isEmpty()) { + cipher.init(if (isEncrypt) Cipher.ENCRYPT_MODE else Cipher.DECRYPT_MODE, keySpec) + } else { + val params: AlgorithmParameterSpec = IvParameterSpec(iv) + cipher.init( + if (isEncrypt) Cipher.ENCRYPT_MODE else Cipher.DECRYPT_MODE, + keySpec, + params + ) + } + cipher.doFinal(data) + } catch (e: Throwable) { + e.printStackTrace() + null + } + } + + } \ No newline at end of file diff --git a/epublib/src/main/java/me/ag2s/epublib/util/ResourceUtil.java b/epublib/src/main/java/me/ag2s/epublib/util/ResourceUtil.java index d03018e26..faf42755f 100644 --- a/epublib/src/main/java/me/ag2s/epublib/util/ResourceUtil.java +++ b/epublib/src/main/java/me/ag2s/epublib/util/ResourceUtil.java @@ -67,9 +67,7 @@ public class ResourceUtil { if (s.length() != 0) { if (s.contains("") - body.append(s); - //.append(""); + body.append("
").append(s).append("
"); } else { body.append("

").append(s).append("

"); } diff --git a/epublib/src/main/java/me/ag2s/epublib/util/StringUtil.java b/epublib/src/main/java/me/ag2s/epublib/util/StringUtil.java index b24a283dd..acb3093e9 100644 --- a/epublib/src/main/java/me/ag2s/epublib/util/StringUtil.java +++ b/epublib/src/main/java/me/ag2s/epublib/util/StringUtil.java @@ -275,13 +275,16 @@ public class StringUtil { } public static String FixTrim(String s) { if (s==null){ - return "null"; + return ""; } Pattern r = Pattern.compile("^[\\s]{1,9}(.*?)[\\s]{1,9}$"); Matcher m = r.matcher(s); if (m.find()) { s= m.group(1); } + if(s==null){ + return ""; + } //移除GBK中文全角空格 s = s.replace(" ", ""); return s;