|
|
|
@ -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., <i>DES/CBC/PKCS5Padding</i>. |
|
|
|
|
* @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 |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |