From f19c35b70d2740d5b852bd884fa80b32d8936ede Mon Sep 17 00:00:00 2001 From: Ztiany Date: Wed, 23 Oct 2019 20:01:40 +0800 Subject: [PATCH] optimize Security/UIKit --- lib_base/build.gradle | 1 + .../base/app/fragment/BaseDialogFragment.kt | 2 +- .../android/base/app/fragment/BaseFragment.kt | 2 +- .../java/com/android/base/app/ui/UIKit.kt | 33 +++- .../com/android/base/rx/SchedulerProvider.kt | 32 +++- .../utils/security/AESCipherStrategy.java | 40 ---- .../android/base/utils/security/AESUtils.java | 177 ++++-------------- .../base/utils/security/CipherStrategy.java | 43 ----- .../utils/security/DESCipherStrategy.java | 45 ----- .../android/base/utils/security/DESUtils.java | 26 +-- .../android/base/utils/security/HexUtils.java | 49 +++++ .../android/base/utils/security/MD5Utils.java | 4 + .../utils/security/RSACipherStrategy.java | 68 ------- .../android/base/utils/security/RSAUtils.java | 51 ++--- .../android/base/utils/security/SHAUtils.java | 4 + .../base/utils/security/SimpleRsa.java | 4 + .../base/utils/security/security-utils.kt | 4 +- 17 files changed, 184 insertions(+), 401 deletions(-) delete mode 100644 lib_base/src/main/java/com/android/base/utils/security/AESCipherStrategy.java delete mode 100644 lib_base/src/main/java/com/android/base/utils/security/CipherStrategy.java delete mode 100644 lib_base/src/main/java/com/android/base/utils/security/DESCipherStrategy.java create mode 100644 lib_base/src/main/java/com/android/base/utils/security/HexUtils.java delete mode 100644 lib_base/src/main/java/com/android/base/utils/security/RSACipherStrategy.java diff --git a/lib_base/build.gradle b/lib_base/build.gradle index 4ed366a..ee394fc 100644 --- a/lib_base/build.gradle +++ b/lib_base/build.gradle @@ -89,6 +89,7 @@ dependencies { api kotlinLibraries.kotlinReflect api kotlinLibraries.kotlinCoroutines api kotlinLibraries.kotlinAndroidCoroutines + api kotlinLibraries.kotlinxCoroutinesRx2 //RxJava api thirdLibraries.rxJava diff --git a/lib_base/src/main/java/com/android/base/app/fragment/BaseDialogFragment.kt b/lib_base/src/main/java/com/android/base/app/fragment/BaseDialogFragment.kt index 676a7cb..a602eb9 100644 --- a/lib_base/src/main/java/com/android/base/app/fragment/BaseDialogFragment.kt +++ b/lib_base/src/main/java/com/android/base/app/fragment/BaseDialogFragment.kt @@ -85,7 +85,7 @@ open class BaseDialogFragment : AppCompatDialogFragment(), LoadingView, OnBackPr */ protected open fun provideLayout(): Any? = null - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + final override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) Timber.tag(tag()).d("-->onViewCreated savedInstanceState = %s", savedInstanceState) if (layoutView !== view) { diff --git a/lib_base/src/main/java/com/android/base/app/fragment/BaseFragment.kt b/lib_base/src/main/java/com/android/base/app/fragment/BaseFragment.kt index 620a75a..12b6e20 100644 --- a/lib_base/src/main/java/com/android/base/app/fragment/BaseFragment.kt +++ b/lib_base/src/main/java/com/android/base/app/fragment/BaseFragment.kt @@ -96,7 +96,7 @@ open class BaseFragment : Fragment(), LoadingView, OnBackPressListener, Fragment */ protected open fun provideLayout(): Any? = null - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + final override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) Timber.tag(tag()).d("-->onViewCreated savedInstanceState = %s", savedInstanceState) if (layoutView !== view) { diff --git a/lib_base/src/main/java/com/android/base/app/ui/UIKit.kt b/lib_base/src/main/java/com/android/base/app/ui/UIKit.kt index cda64a9..8c96c6d 100644 --- a/lib_base/src/main/java/com/android/base/app/ui/UIKit.kt +++ b/lib_base/src/main/java/com/android/base/app/ui/UIKit.kt @@ -23,6 +23,7 @@ interface UIErrorHandler { fun H.handleLiveState( liveData: LiveData>, forceLoading: Boolean = true, + onError: ((Throwable) -> Unit)? = null, onSuccess: (T?) -> Unit ) where H : UIErrorHandler, H : LoadingView, H : LifecycleOwner { @@ -30,8 +31,13 @@ fun H.handleLiveState( when { state.isError -> { Timber.d("handleLiveState -> isError") - dismissLoadingDialog() - handleError(state.error()) + dismissLoadingDialog(Sword.get().minimumShowingDialogMills()) { + if (onError != null) { + onError(state.error()) + } else { + handleError(state.error()) + } + } } state.isLoading -> { Timber.d("handleLiveState -> isLoading") @@ -39,8 +45,7 @@ fun H.handleLiveState( } state.isSuccess -> { Timber.d("handleLiveState -> isSuccess") - val minimumShowingDialogMills = Sword.get().minimumShowingDialogMills() - dismissLoadingDialog(minimumShowingDialogMills) { + dismissLoadingDialog(Sword.get().minimumShowingDialogMills()) { onSuccess(state.get()) } }//success end @@ -49,6 +54,18 @@ fun H.handleLiveState( } +fun H.handleLiveState2( + liveData: LiveData>, + forceLoading: Boolean = true, + handler: StateHandler.() -> Unit +) where H : UIErrorHandler, H : LoadingView, H : LifecycleOwner { + + liveData.observe(this, Observer { state -> + handleState(state, forceLoading, handler) + }) + +} + fun LoadingView.handleState( state: State, forceLoading: Boolean = true, @@ -61,8 +78,9 @@ fun LoadingView.handleState( when { state.isError -> { Timber.d("handleState -> isError") - dismissLoadingDialog() - stateHandler.onError?.invoke(state.error()) + dismissLoadingDialog(Sword.get().minimumShowingDialogMills()) { + stateHandler.onError?.invoke(state.error()) + } } state.isLoading -> { Timber.d("handleState -> isLoading") @@ -70,8 +88,7 @@ fun LoadingView.handleState( } state.isSuccess -> { Timber.d("handleState -> isSuccess") - val minimumShowingDialogMills = Sword.get().minimumShowingDialogMills() - dismissLoadingDialog(minimumShowingDialogMills) { + dismissLoadingDialog(Sword.get().minimumShowingDialogMills()) { stateHandler.onSuccess?.invoke(state.get()) if (state.hasData()) { stateHandler.onSuccessWithData?.invoke(state.data()) diff --git a/lib_base/src/main/java/com/android/base/rx/SchedulerProvider.kt b/lib_base/src/main/java/com/android/base/rx/SchedulerProvider.kt index 5070884..19b25bd 100644 --- a/lib_base/src/main/java/com/android/base/rx/SchedulerProvider.kt +++ b/lib_base/src/main/java/com/android/base/rx/SchedulerProvider.kt @@ -1,9 +1,13 @@ @file:JvmName("SchedulerProviders") + package com.android.base.rx import io.reactivex.Scheduler import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.schedulers.Schedulers +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.rx2.asCoroutineDispatcher /** @@ -19,6 +23,12 @@ interface SchedulerProvider { fun database(): Scheduler + fun ioDispatcher(): CoroutineDispatcher + + fun defaultDispatcher(): CoroutineDispatcher + + fun uiDispatcher(): CoroutineDispatcher + } fun newDefaultSchedulerProvider(): SchedulerProvider { @@ -27,6 +37,26 @@ fun newDefaultSchedulerProvider(): SchedulerProvider { private class DefaultSchedulerProvider : SchedulerProvider { + private val ioDispatcher by lazy { + io().asCoroutineDispatcher() + } + + private val defaultDispatcher by lazy { + io().asCoroutineDispatcher() + } + + override fun ioDispatcher(): CoroutineDispatcher { + return ioDispatcher + } + + override fun defaultDispatcher(): CoroutineDispatcher { + return defaultDispatcher + } + + override fun uiDispatcher(): CoroutineDispatcher { + return Dispatchers.Main + } + override fun computation(): Scheduler { return Schedulers.computation() } @@ -43,4 +73,4 @@ private class DefaultSchedulerProvider : SchedulerProvider { return Schedulers.single() } -} +} \ No newline at end of file diff --git a/lib_base/src/main/java/com/android/base/utils/security/AESCipherStrategy.java b/lib_base/src/main/java/com/android/base/utils/security/AESCipherStrategy.java deleted file mode 100644 index f9ce0a5..0000000 --- a/lib_base/src/main/java/com/android/base/utils/security/AESCipherStrategy.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.android.base.utils.security; - -import java.io.UnsupportedEncodingException; - -/** - * Reference: https://github.com/zhengxiaopeng/Rocko-Android-Demos - */ -public class AESCipherStrategy extends CipherStrategy { - - private String key; - - public AESCipherStrategy(String key) { - this.key = key; - } - - @Override - public String encrypt(String content) { - byte[] encryptByte = new byte[0]; - try { - encryptByte = AESUtils.encryptData(content.getBytes(CHARSET), key); - } catch (UnsupportedEncodingException e) { - e.printStackTrace(); - } - return encodeConvert(encryptByte); - } - - @Override - public String decrypt(String encryptContent) { - byte[] encryptByte = decodeConvert(encryptContent); - byte[] decryptByte = AESUtils.decryptData(encryptByte, key); - String result = ""; - try { - result = new String(decryptByte, CHARSET); - } catch (UnsupportedEncodingException e) { - e.printStackTrace(); - } - return result; - } - -} \ No newline at end of file diff --git a/lib_base/src/main/java/com/android/base/utils/security/AESUtils.java b/lib_base/src/main/java/com/android/base/utils/security/AESUtils.java index 32fe918..1d7ac61 100644 --- a/lib_base/src/main/java/com/android/base/utils/security/AESUtils.java +++ b/lib_base/src/main/java/com/android/base/utils/security/AESUtils.java @@ -1,71 +1,53 @@ -/* - * Copyright 2015 Rocko (http://rocko.xyz) . - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - package com.android.base.utils.security; -import java.nio.charset.StandardCharsets; - import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; +import androidx.annotation.Nullable; + + /** * AES 对称加密 */ +@SuppressWarnings("unused") public class AESUtils { - /** - * 算法/模式/填充 * - */ - private static final String CIPHER_MODE = "AES"; + //算法/模式/填充 + public static String AES = "AES"; + public static String AES_CBC_ISO10126PADDING = "AES/CBC/ISO10126Padding"; + public static String AES_CBC_NOPADDING = "AES/CBC/NoPadding"; + public static String AES_CBC_PKCS5PADDING = "AES/CBC/PKCS5Padding"; + public static String AES_CFB_ISO10126PADDING = "AES/CFB/ISO10126Padding"; + public static String AES_CFB_NOPADDING = "AES/CFB/NoPadding"; + public static String AES_CFB_PKCS5PADDING = "AES/CFB/PKCS5Padding"; + public static String AES_CTR_ISO10126PADDING = "AES/CTR/ISO10126Padding"; + public static String AES_CTR_NOPADDING = "AES/CTR/NoPadding"; + public static String AES_CTR_PKCS5PADDING = "AES/CTR/PKCS5Padding"; + public static String AES_CTS_ISO10126PADDING = "AES/CTS/ISO10126Padding"; + public static String AES_CTS_NOPADDING = "AES/CTS/NoPadding"; + public static String AES_CTS_PKCS5PADDING = "AES/CTS/PKCS5Padding"; + public static String AES_ECB_ISO10126PADDING = "AES/ECB/ISO10126Padding"; + public static String AES_ECB_NOPADDING = "AES/ECB/NoPadding"; + public static String AES_ECB_PKCS5PADDING = "AES/ECB/PKCS5Padding"; + public static String AES_OFB_ISO10126PADDING = "AES/OFB/ISO10126Padding"; + public static String AES_OFB_NOPADDING = "AES/OFB/NoPadding"; + public static String AES_OFB_PKCS5PADDING = "AES/OFB/PKCS5Padding"; - /** - * 创建密钥 - * - * @param password 例如:"0123456701234567" 128位 16*8
- * 所有密钥长度不能超过16字符中文占两个。192 24; 256 32 - * @return SecretKeySpec 实例 - */ - private static SecretKeySpec generateAESKey(String password) { - byte[] data; - StringBuilder sb = new StringBuilder(); - sb.append(password); - while (sb.length() < 16) - sb.append("0"); - if (sb.length() > 16) - sb.setLength(16); - try { - data = sb.toString().getBytes(StandardCharsets.UTF_8); - return new SecretKeySpec(data, CIPHER_MODE); - } catch (Exception e) { - e.printStackTrace(); - return null; + private static final int LIMIT_LEN = 16; + + private static SecretKeySpec generateAESKey(String algorithm, String password) { + byte[] passwordData = password.getBytes(); + if (passwordData.length != LIMIT_LEN) { + throw new IllegalArgumentException("password 长度必须等于16"); } + return new SecretKeySpec(passwordData, algorithm); } - /** - * 加密字节数据 - * - * @param content 需要加密的字节数组 - * @param password 密钥 128 <16个字节 192 <24,256 <32个字节 - * @return 加密完后的字节数组 - */ - public static byte[] encryptData(byte[] content, String password) { + @Nullable + public static byte[] encryptData(byte[] content, String algorithm, String password) { try { - SecretKeySpec key = generateAESKey(password); - Cipher cipher = Cipher.getInstance(CIPHER_MODE); + SecretKeySpec key = generateAESKey(algorithm, password); + Cipher cipher = Cipher.getInstance(algorithm); cipher.init(Cipher.ENCRYPT_MODE, key); return cipher.doFinal(content); } catch (Exception e) { @@ -74,35 +56,11 @@ public class AESUtils { return null; } - /** - * 加密(结果为16进制字符串), UTF-8 编码 - * - * @param content 要加密的字符串 - * @param password 密钥 - * @return 加密后的16进制字符串 - */ - public static String encryptData(String content, String password) { - byte[] data = null; - try { - data = content.getBytes(StandardCharsets.UTF_8); - } catch (Exception e) { - e.printStackTrace(); - } - data = encryptData(data, password); - return byte2hex(data); - } - - /** - * 解密字节数组 UTF-8 - * - * @param content - * @param password - * @return - */ - public static byte[] decryptData(byte[] content, String password) { + @Nullable + public static byte[] decryptData(byte[] content, String algorithm, String password) { try { - SecretKeySpec key = generateAESKey(password); - Cipher cipher = Cipher.getInstance(CIPHER_MODE); + SecretKeySpec key = generateAESKey(algorithm, password); + Cipher cipher = Cipher.getInstance(algorithm); cipher.init(Cipher.DECRYPT_MODE, key); return cipher.doFinal(content); } catch (Exception e) { @@ -111,61 +69,4 @@ public class AESUtils { return null; } - /** - * 解密16进制的字符串为字符串 * - */ - public static String decryptData(String content, String password) { - byte[] data = null; - try { - data = hex2byte(content); - } catch (Exception e) { - e.printStackTrace(); - } - data = decryptData(data, password); - if (data == null) - return null; - String result = null; - result = new String(data, StandardCharsets.UTF_8); - return result; - } - - /** - * 字节数组转成16进制字符串 - * - * @return 16进制字符串 - */ - public static String byte2hex(byte[] bytes) { // 一个字节的数, - StringBuilder sb = new StringBuilder(bytes.length * 2); - String tmp; - for (byte theByte : bytes) { - // 整数转成十六进制表示 - tmp = (Integer.toHexString(theByte & 0XFF)); - if (tmp.length() == 1) { - sb.append("0"); - } - sb.append(tmp); - } - return sb.toString().toUpperCase(); // 转成大写 - } - - /** - * 将hex字符串转换成字节数组 - * - * @param inputString 16进制的字符串 - * @return 字节数组 - */ - public static byte[] hex2byte(String inputString) { - if (inputString == null || inputString.length() < 2) { - return new byte[0]; - } - inputString = inputString.toLowerCase(); - int l = inputString.length() / 2; - byte[] result = new byte[l]; - for (int i = 0; i < l; ++i) { - String tmp = inputString.substring(2 * i, 2 * i + 2); - result[i] = (byte) (Integer.parseInt(tmp, 16) & 0xFF); - } - return result; - } - } \ No newline at end of file diff --git a/lib_base/src/main/java/com/android/base/utils/security/CipherStrategy.java b/lib_base/src/main/java/com/android/base/utils/security/CipherStrategy.java deleted file mode 100644 index 77774a0..0000000 --- a/lib_base/src/main/java/com/android/base/utils/security/CipherStrategy.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.android.base.utils.security; - - -import android.util.Base64; - -/** - * Reference: https://github.com/zhengxiaopeng/Rocko-Android-Demos - */ -abstract class CipherStrategy { - - final static String CHARSET = "UTF-8"; - - /** - * 将加密内容的 Base64 编码转换为二进制内容 - */ - protected byte[] decodeConvert(String str) { - return Base64.decode(str, Base64.DEFAULT); - } - - /** - * 对加密后的二进制结果转换为 Base64 编码 - */ - protected String encodeConvert(byte[] bytes) { - return new String(Base64.encode(bytes, Base64.DEFAULT)); - } - - /** - * 对字符串进行加密 - * - * @param content 需要加密的字符串 - * @return - */ - public abstract String encrypt(String content); - - /** - * 对字符串进行解密 - * - * @param encryptContent 加密内容的 Base64 编码 - * @return - */ - public abstract String decrypt(String encryptContent); - -} diff --git a/lib_base/src/main/java/com/android/base/utils/security/DESCipherStrategy.java b/lib_base/src/main/java/com/android/base/utils/security/DESCipherStrategy.java deleted file mode 100644 index 116ce4f..0000000 --- a/lib_base/src/main/java/com/android/base/utils/security/DESCipherStrategy.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.android.base.utils.security; - - -import java.io.UnsupportedEncodingException; - -/** - * Reference: https://github.com/zhengxiaopeng/Rocko-Android-Demos - */ -public class DESCipherStrategy extends CipherStrategy { - - private String key;// 解密密码 - - /** - * @param key 加解密的 key - */ - public DESCipherStrategy(String key) { - this.key = key; - } - - @Override - public String encrypt(String content) { - byte[] encryptByte = null; - try { - encryptByte = DESUtils.encrypt(content.getBytes(CHARSET), key); - } catch (UnsupportedEncodingException e) { - e.printStackTrace(); - } - return encodeConvert(encryptByte); - } - - @Override - public String decrypt(String encryptContent) { - byte[] encryptByte = decodeConvert(encryptContent); - byte[] decryptByte = DESUtils.decrypt(encryptByte, key); - String result = ""; - try { - result = new String(decryptByte, CHARSET); - } catch (UnsupportedEncodingException e) { - e.printStackTrace(); - } - - return result; - } - -} diff --git a/lib_base/src/main/java/com/android/base/utils/security/DESUtils.java b/lib_base/src/main/java/com/android/base/utils/security/DESUtils.java index 53334dd..90107dd 100644 --- a/lib_base/src/main/java/com/android/base/utils/security/DESUtils.java +++ b/lib_base/src/main/java/com/android/base/utils/security/DESUtils.java @@ -1,19 +1,3 @@ -/* - * Copyright 2015 Rocko (http://rocko.xyz) . - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - package com.android.base.utils.security; import java.security.SecureRandom; @@ -23,7 +7,9 @@ import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.DESKeySpec; -@SuppressWarnings("WeakerAccess") +import androidx.annotation.Nullable; + +@SuppressWarnings("unused") public class DESUtils { /** @@ -32,14 +18,15 @@ public class DESUtils { * @param bytesContent 待加密内容 * @param key 加密的密钥 */ + @Nullable public static byte[] encrypt(byte[] bytesContent, String key) { try { SecureRandom random = new SecureRandom(); DESKeySpec desKey = new DESKeySpec(key.getBytes()); SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); - SecretKey securekey = keyFactory.generateSecret(desKey); + SecretKey secretKey = keyFactory.generateSecret(desKey); Cipher cipher = Cipher.getInstance("DES"); - cipher.init(Cipher.ENCRYPT_MODE, securekey, random); + cipher.init(Cipher.ENCRYPT_MODE, secretKey, random); return cipher.doFinal(bytesContent); } catch (Throwable e) { e.printStackTrace(); @@ -53,6 +40,7 @@ public class DESUtils { * @param content 待解密内容 * @param key 解密的密钥 */ + @Nullable public static byte[] decrypt(byte[] content, String key) { try { SecureRandom random = new SecureRandom(); diff --git a/lib_base/src/main/java/com/android/base/utils/security/HexUtils.java b/lib_base/src/main/java/com/android/base/utils/security/HexUtils.java new file mode 100644 index 0000000..9160690 --- /dev/null +++ b/lib_base/src/main/java/com/android/base/utils/security/HexUtils.java @@ -0,0 +1,49 @@ +package com.android.base.utils.security; + +/** + * @author Ztiany + * Email: ztiany3@gmail.com + * Date : 2019-10-23 15:09 + */ +public class HexUtils { + + /** + * 字节数组转成16进制字符串 + * + * @return 16进制字符串 + */ + public static String byte2hex(byte[] bytes) { // 一个字节的数, + StringBuilder sb = new StringBuilder(bytes.length * 2); + String tmp; + for (byte theByte : bytes) { + // 整数转成十六进制表示 + tmp = (Integer.toHexString(theByte & 0XFF)); + if (tmp.length() == 1) { + sb.append("0"); + } + sb.append(tmp); + } + return sb.toString().toUpperCase(); // 转成大写 + } + + /** + * 将hex字符串转换成字节数组 + * + * @param inputString 16进制的字符串 + * @return 字节数组 + */ + public static byte[] hex2byte(String inputString) { + if (inputString == null || inputString.length() < 2) { + return new byte[0]; + } + inputString = inputString.toLowerCase(); + int l = inputString.length() / 2; + byte[] result = new byte[l]; + for (int i = 0; i < l; ++i) { + String tmp = inputString.substring(2 * i, 2 * i + 2); + result[i] = (byte) (Integer.parseInt(tmp, 16) & 0xFF); + } + return result; + } + +} diff --git a/lib_base/src/main/java/com/android/base/utils/security/MD5Utils.java b/lib_base/src/main/java/com/android/base/utils/security/MD5Utils.java index 074f138..c8c4d41 100644 --- a/lib_base/src/main/java/com/android/base/utils/security/MD5Utils.java +++ b/lib_base/src/main/java/com/android/base/utils/security/MD5Utils.java @@ -6,6 +6,9 @@ import java.nio.charset.StandardCharsets; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; +import androidx.annotation.Nullable; + +@SuppressWarnings("unused") public class MD5Utils { private static final char[] HEX_DIGITS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; @@ -22,6 +25,7 @@ public class MD5Utils { /** * 文件加密 */ + @Nullable public static String md5file(String filename) { InputStream fis; byte[] buffer = new byte[1024]; diff --git a/lib_base/src/main/java/com/android/base/utils/security/RSACipherStrategy.java b/lib_base/src/main/java/com/android/base/utils/security/RSACipherStrategy.java deleted file mode 100644 index 50b6ca2..0000000 --- a/lib_base/src/main/java/com/android/base/utils/security/RSACipherStrategy.java +++ /dev/null @@ -1,68 +0,0 @@ -package com.android.base.utils.security; - -import java.io.InputStream; -import java.security.PrivateKey; -import java.security.PublicKey; - -/** - * Reference: https://github.com/zhengxiaopeng/Rocko-Android-Demos - */ -public class RSACipherStrategy extends CipherStrategy { - - private PublicKey mPublicKey; - private PrivateKey mPrivateKey; - - public void initPublicKey(String publicKeyContentStr) { - try { - mPublicKey = RSAUtils.loadPublicKey(publicKeyContentStr); - } catch (Exception e) { - e.printStackTrace(); - } - } - - public void initPublicKey(InputStream publicKeyIs) { - try { - mPublicKey = RSAUtils.loadPublicKey(publicKeyIs); - } catch (Exception e) { - e.printStackTrace(); - } - } - - public void initPrivateKey(String privateKeyContentStr) { - try { - mPrivateKey = RSAUtils.loadPrivateKey(privateKeyContentStr); - } catch (Exception e) { - e.printStackTrace(); - } - } - - public void initPrivateKey(InputStream privateIs) { - try { - mPrivateKey = RSAUtils.loadPrivateKey(privateIs); - } catch (Exception e) { - e.printStackTrace(); - } - } - - @Override - public String encrypt(String content) { - if (mPublicKey == null) { - throw new NullPointerException("PublicKey is null, please initialize it first"); - } - byte[] encryptByte = RSAUtils.encryptData(content.getBytes(), mPublicKey); - - return encodeConvert(encryptByte); - } - - @Override - public String decrypt(String encryptContent) { - if (mPrivateKey == null) { - throw new NullPointerException("PrivateKey is null, please initialize it first"); - } - byte[] encryptByte = decodeConvert(encryptContent); - byte[] decryptByte = RSAUtils.decryptData(encryptByte, mPrivateKey); - - return new String(decryptByte); - } - -} \ No newline at end of file diff --git a/lib_base/src/main/java/com/android/base/utils/security/RSAUtils.java b/lib_base/src/main/java/com/android/base/utils/security/RSAUtils.java index f3b081b..e1776e9 100644 --- a/lib_base/src/main/java/com/android/base/utils/security/RSAUtils.java +++ b/lib_base/src/main/java/com/android/base/utils/security/RSAUtils.java @@ -1,19 +1,3 @@ -/* - * Copyright 2015 Rocko (http://rocko.xyz) . - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - package com.android.base.utils.security; import android.util.Base64; @@ -36,10 +20,9 @@ import java.security.spec.X509EncodedKeySpec; import javax.crypto.Cipher; +import androidx.annotation.Nullable; -/** - * @author Mr.Zheng - */ +@SuppressWarnings("WeakerAccess,unused") public final class RSAUtils { private final static String KEY_PAIR = "RSA"; @@ -69,13 +52,13 @@ public final class RSAUtils { } /** - * 用公钥加密
- * 每次加密的字节数,不能超过密钥的长度值减去11 + * 用公钥加密,每次加密的字节数,不能超过密钥的长度值减去11 * * @param data 需加密数据的byte数据 * @param publicKey 公钥 * @return 加密后的byte型数据 */ + @Nullable public static byte[] encryptData(byte[] data, PublicKey publicKey) { try { Cipher cipher = Cipher.getInstance(CIPHER); @@ -95,6 +78,7 @@ public final class RSAUtils { * @param encryptedData 经过encryptedData()加密返回的byte数据 * @param privateKey 私钥 */ + @Nullable public static byte[] decryptData(byte[] encryptedData, PrivateKey privateKey) { try { Cipher cipher = Cipher.getInstance(CIPHER); @@ -108,11 +92,10 @@ public final class RSAUtils { /** * 通过公钥byte[](publicKey.getEncoded())将公钥还原,适用于RSA算法 * - * @throws NoSuchAlgorithmException - * @throws InvalidKeySpecException + * @throws NoSuchAlgorithmException NoSuchAlgorithm + * @throws InvalidKeySpecException InvalidKeySpec */ - public static PublicKey getPublicKey(byte[] keyBytes) throws NoSuchAlgorithmException, - InvalidKeySpecException { + public static PublicKey getPublicKey(byte[] keyBytes) throws NoSuchAlgorithmException, InvalidKeySpecException { X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_PAIR); return keyFactory.generatePublic(keySpec); @@ -121,11 +104,10 @@ public final class RSAUtils { /** * 通过私钥byte[]将公钥还原,适用于RSA算法 * - * @throws NoSuchAlgorithmException - * @throws InvalidKeySpecException + * @throws NoSuchAlgorithmException NoSuchAlgorithm + * @throws InvalidKeySpecException InvalidKeySpec */ - public static PrivateKey getPrivateKey(byte[] keyBytes) throws NoSuchAlgorithmException, - InvalidKeySpecException { + public static PrivateKey getPrivateKey(byte[] keyBytes) throws NoSuchAlgorithmException, InvalidKeySpecException { PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_PAIR); return keyFactory.generatePrivate(keySpec); @@ -134,11 +116,10 @@ public final class RSAUtils { /** * 使用N、e值还原公钥 * - * @throws NoSuchAlgorithmException - * @throws InvalidKeySpecException + * @throws NoSuchAlgorithmException NoSuchAlgorithm + * @throws InvalidKeySpecException InvalidKeySpec */ - public static PublicKey getPublicKey(String modulus, String publicExponent) - throws NoSuchAlgorithmException, InvalidKeySpecException { + public static PublicKey getPublicKey(String modulus, String publicExponent) throws NoSuchAlgorithmException, InvalidKeySpecException { BigInteger bigIntModulus = new BigInteger(modulus); BigInteger bigIntPrivateExponent = new BigInteger(publicExponent); RSAPublicKeySpec keySpec = new RSAPublicKeySpec(bigIntModulus, bigIntPrivateExponent); @@ -149,8 +130,8 @@ public final class RSAUtils { /** * 使用N、d值还原私钥 * - * @throws NoSuchAlgorithmException - * @throws InvalidKeySpecException + * @throws NoSuchAlgorithmException NoSuchAlgorithm + * @throws InvalidKeySpecException InvalidKeySpec */ public static PrivateKey getPrivateKey(String modulus, String privateExponent) throws NoSuchAlgorithmException, InvalidKeySpecException { BigInteger bigIntModulus = new BigInteger(modulus); diff --git a/lib_base/src/main/java/com/android/base/utils/security/SHAUtils.java b/lib_base/src/main/java/com/android/base/utils/security/SHAUtils.java index b8622ec..3eca077 100644 --- a/lib_base/src/main/java/com/android/base/utils/security/SHAUtils.java +++ b/lib_base/src/main/java/com/android/base/utils/security/SHAUtils.java @@ -4,6 +4,8 @@ import java.nio.charset.StandardCharsets; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; +import androidx.annotation.Nullable; + /** * @author Ztiany * Email: ztiany3@gmail.com @@ -14,10 +16,12 @@ public class SHAUtils { private static final String SHA256 = "SHA256"; + @Nullable public static byte[] toSHA256(String content) { return toSHA256(content.getBytes(StandardCharsets.UTF_8)); } + @Nullable public static byte[] toSHA256(byte[] bytes) { try { MessageDigest md = MessageDigest.getInstance(SHA256); diff --git a/lib_base/src/main/java/com/android/base/utils/security/SimpleRsa.java b/lib_base/src/main/java/com/android/base/utils/security/SimpleRsa.java index 77e67e9..e1a0dfd 100644 --- a/lib_base/src/main/java/com/android/base/utils/security/SimpleRsa.java +++ b/lib_base/src/main/java/com/android/base/utils/security/SimpleRsa.java @@ -16,6 +16,8 @@ import java.security.spec.X509EncodedKeySpec; import javax.crypto.Cipher; +import androidx.annotation.Nullable; + public class SimpleRsa { @@ -49,6 +51,7 @@ public class SimpleRsa { * @param content 加密字符串 * @return 加密后的字符串 */ + @Nullable public static String encryptByPublic(String content, String RSA_PUBLIC_KEY) { try { PublicKey pubKey = getPublicKeyFromX509(ALGORITHM, RSA_PUBLIC_KEY); @@ -68,6 +71,7 @@ public class SimpleRsa { * @param content 密文 * @return 解密后的字符串 */ + @Nullable public static String decryptByPublic(String content, String RSA_PUBLIC_KEY) { try { PublicKey pubkey = getPublicKeyFromX509(ALGORITHM, RSA_PUBLIC_KEY); diff --git a/lib_base/src/main/java/com/android/base/utils/security/security-utils.kt b/lib_base/src/main/java/com/android/base/utils/security/security-utils.kt index 609842e..4f630d7 100644 --- a/lib_base/src/main/java/com/android/base/utils/security/security-utils.kt +++ b/lib_base/src/main/java/com/android/base/utils/security/security-utils.kt @@ -3,10 +3,10 @@ package com.android.base.utils.security import android.annotation.SuppressLint fun md5(content: String): String { - return MD5Utils.md5(content) + return MD5Utils.md5(content) ?: "" } @SuppressLint("DefaultLocale") fun md5UpperCase(content: String): String { - return MD5Utils.md5(content).toUpperCase() + return MD5Utils.md5(content)?.toUpperCase() ?: "" }